/* ioctl command for KR3DM device file */ static int kr3dm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; struct kr3dm_data *kr3dm = file->private_data; s64 delay_ns; struct kr3dm_acc data; int i; struct kr3dm_acceldata sum = { 0, }; /* cmd mapping */ switch (cmd) { case KR3DM_IOCTL_SET_DELAY: if (copy_from_user(&delay_ns, (void __user *)arg, sizeof(delay_ns))) return -EFAULT; err = kr3dm_set_delay(kr3dm, delay_ns); break; case KR3DM_IOCTL_GET_DELAY: delay_ns = kr3dm_get_delay(kr3dm); if (put_user(delay_ns, (s64 __user *)arg)) return -EFAULT; break; case KR3DM_IOCTL_READ_ACCEL_XYZ: mutex_lock(&kr3dm->lock); for (i = 0; i < READ_REPEAT; i++) { err = kr3dm_read_accel_xyz(kr3dm, &data); if (err) break; sum.x += data.x; sum.y += data.y; sum.z += data.z; } mutex_unlock(&kr3dm->lock); if (err) return err; if (copy_to_user((void __user *)arg, &sum, sizeof(sum))) return -EFAULT; break; default: err = -EINVAL; break; } return err; }
int kr3dm_acc_start(void) { int result; struct device *dev_t; kr3dmacc_t accels; /* only for test */ result = register_chrdev( KR3DM_MAJOR, "kr3dm", &kr3dm_acc_fops); if (result < 0) { return result; } kr3dm_acc_class = class_create (THIS_MODULE, "KR3DM-dev"); if (IS_ERR(kr3dm_acc_class)) { unregister_chrdev( KR3DM_MAJOR, "kr3dm" ); return PTR_ERR( kr3dm_acc_class ); } dev_t = device_create( kr3dm_acc_class, NULL, MKDEV(KR3DM_MAJOR, 0), "%s", "kr3dm"); if (IS_ERR(dev_t)) { return PTR_ERR(dev_t); } result = i2c_acc_kr3dm_init(); if(result) { return result; } kr3dm_chip_init(); #if DEBUG printk("[KR3DM] read_xyz ==========================\n"); kr3dm_read_accel_xyz( &accels ); printk("[KR3DM] x = %d / y = %d / z = %d\n", accels.x, accels.y, accels.z ); printk("[KR3DM] ======================kr3dm_acc_start Ready for use !!!!! =============\n"); #endif return 0; }
int kr3dm_acc_start(void) { int result; struct device *dev_t; #ifdef SECURITY_HOLE_SUPPORT int err; struct input_dev *input_dev; #endif kr3dmacc_t accels; /* only for test */ result = register_chrdev( KR3DM_MAJOR, "kr3dm", &kr3dm_acc_fops); if (result < 0) { return result; } kr3dm_acc_class = class_create (THIS_MODULE, "KR3DM-dev"); if (IS_ERR(kr3dm_acc_class)) { unregister_chrdev( KR3DM_MAJOR, "kr3dm" ); return PTR_ERR( kr3dm_acc_class ); } dev_t = device_create( kr3dm_acc_class, NULL, MKDEV(KR3DM_MAJOR, 0), "%s", "kr3dm"); if (IS_ERR(dev_t)) { return PTR_ERR(dev_t); } #ifdef SECURITY_HOLE_SUPPORT //mutex_init(&kr3dm.power_lock); /* hrtimer settings. we poll for light values using a timer. */ hrtimer_init(&kr3dm.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kr3dm.acc_poll_delay = ns_to_ktime(240 * NSEC_PER_MSEC); kr3dm.timer.function = kr3dm_timer_func; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ kr3dm.wq = create_singlethread_workqueue("kr3dm_wq"); if (!kr3dm.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(&kr3dm.work_acc, kr3dm_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, &kr3dm); 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; } kr3dm.acc_input_dev = input_dev; err = sysfs_create_group(&input_dev->dev.kobj,&acc_attribute_group); if (err) { printk("Creating kr3dm attribute group failed"); goto error_device; } ////////////////////////////////////////////////////////////////////////////// #endif result = i2c_acc_kr3dm_init(); if(result) { return result; } kr3dm_chip_init(); #if DEBUG printk("[KR3DM] read_xyz ==========================\n"); kr3dm_read_accel_xyz( &accels ); printk("[KR3DM] x = %d / y = %d / z = %d\n", accels.x, accels.y, accels.z ); printk("[KR3DM] ======================kr3dm_acc_start Ready for use !!!!! =============\n"); #endif return 0; error_device: sysfs_remove_group(&input_dev->dev.kobj, &acc_attribute_group); err_input_register_device_light: input_unregister_device(kr3dm.acc_input_dev); err_input_allocate_device_light: destroy_workqueue(kr3dm.wq); err_create_workqueue: //mutex_destroy(&kr3dm.power_lock); exit: return err; }
int kr3dm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int err = 0; unsigned char data[3]; kr3dmacc_t accels; unsigned char val1 = 0x27; /* check cmd */ if(_IOC_TYPE(cmd) != KR3DM_IOC_MAGIC) { printk("cmd magic type error\n"); return -ENOTTY; } if(_IOC_NR(cmd) > KR3DM_IOC_MAXNR) { printk("cmd number error\n"); 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) { printk("cmd access_ok error\n"); return -EFAULT; } switch(cmd) { case KR3DM_READ_ACCEL_XYZ: err = kr3dm_read_accel_xyz(&accels); if(copy_to_user((kr3dmacc_t*)arg, &accels, sizeof(kr3dmacc_t))!=0) { printk("copy_to error\n"); return -EFAULT; } return err; case KR3DM_SET_RANGE: if(copy_from_user(data,(unsigned char*)arg,1)!=0) { printk("[KR3DM] copy_from_user error\n"); return -EFAULT; } err = kr3dm_set_range(*data); return err; case KR3DM_SET_MODE: if(copy_from_user(data,(unsigned char*)arg,1)!=0) { printk("[KR3DM] copy_from_user error\n"); return -EFAULT; } err = kr3dm_set_mode(*data); return err; case KR3DM_SET_BANDWIDTH: if(copy_from_user(data,(unsigned char*)arg,1)!=0) { printk("[KR3DM] copy_from_user error\n"); return -EFAULT; } err = kr3dm_set_bandwidth(*data); return err; default: return 0; } return 0; }