static ssize_t bma250_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct bma250_data *bma250 = i2c_get_clientdata(client); bma250_read_accel_xyz(bma250->bma250_client, &bma250->value); return count; }
static void bma250_work_func(struct work_struct *work) { struct bma250_data *bma250 = container_of((struct delayed_work *)work, struct bma250_data, work); static struct bma250acc acc; unsigned long delay = msecs_to_jiffies(atomic_read(&bma250->delay)); bma250_read_accel_xyz(bma250->bma250_client, &acc); input_report_abs(bma250->input, ABS_X, acc.x); input_report_abs(bma250->input, ABS_Y, acc.y); input_report_abs(bma250->input, ABS_Z, acc.z); input_sync(bma250->input); bma250->value = acc; schedule_delayed_work(&bma250->work, delay); }
static void bma250_work_func(struct work_struct *work) { struct bma250_data *bma250 = container_of((struct delayed_work *)work, struct bma250_data, work); static struct bma250acc acc; unsigned long delay = msecs_to_jiffies(atomic_read(&bma250->delay)); bma250_read_accel_xyz(bma250->bma250_client, &acc); /*adjust the data output for skud compatible */ input_report_rel(bma250->input, REL_RX, acc.y * 4); input_report_rel(bma250->input, REL_RY, acc.x * 4); input_report_rel(bma250->input, REL_RZ, acc.z * 4); input_sync(bma250->input); mutex_lock(&bma250->value_mutex); bma250->value = acc; mutex_unlock(&bma250->value_mutex); schedule_delayed_work(&bma250->work, delay); }
/* ioctl command for BMA250 device file */ static long bma250_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *pa = (void __user *)arg; int err = 0; bma250acc_t acc; int vec[3] = {0}; #ifdef BMA250_DEBUG //printk(KERN_INFO "%s,cmd = %d , BMA250_IOC_READXYZ = %d\n",__FUNCTION__,cmd,BMA250_IOC_READXYZ); #endif /* cmd mapping */ switch(cmd) { case BMA250_IOC_READXYZ: bma250_read_accel_xyz(&acc); vec[0] = acc.x; vec[1] = acc.y; vec[2] = acc.z; // printk("[X - %d] [Y - %d] [Z - %d]\n", // vec[0], vec[1], vec[2]); // printk("[acc.x - %d] [acc.y - %d] [acc.z - %d]\n", // acc.x, acc.y, acc.z); if (copy_to_user(pa, vec, sizeof(vec))) { #ifdef BMA250_DEBUG printk(KERN_INFO "copy_to error\n"); #endif return -EFAULT; } break; case BMA250_IOC_READSTATUS: bma250_read_accel_xyz(&acc); vec[0] = acc.x; vec[1] = acc.y; vec[2] = acc.z; if (copy_to_user(pa, vec, sizeof(vec))) { #ifdef BMA250_DEBUG printk(KERN_INFO "copy_to error\n"); #endif return -EFAULT; } break; case BMA250_IOC_PWRDN: bma250_set_mode(bma250_MODE_SUSPEND); break; case BMA250_IOC_PWRON: bma250_set_mode(bma250_MODE_NORMAL); break; default: return 0; } return 0; }
static ssize_t bma250_fast_calibration_z_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; signed char tmp; unsigned int timeout = 0; int error; struct i2c_client *client = to_i2c_client(dev); struct bma250_data *bma250 = i2c_get_clientdata(client); struct bma250acc acc_cal; struct bma250acc acc_cal_pre; error = strict_strtoul(buf, 10, &data); if (error) return error; bma250_read_accel_xyz(bma250->bma250_client, &acc_cal_pre); mdelay(50); if (bma250_set_offset_target_z(bma250->bma250_client, (unsigned char)data) < 0) return -EINVAL; if (bma250_set_cal_trigger(bma250->bma250_client, 3) < 0) return -EINVAL; atomic_set(&bma250->fast_calib_x_rslt, 0); do { mdelay(2); bma250_get_cal_ready(bma250->bma250_client, &tmp); bma250_read_accel_xyz(bma250->bma250_client, &acc_cal); if( (tmp == 0) && ((abs(acc_cal.x - acc_cal_pre.x) > BMA250_SHAKING_DETECT_THRESHOLD) || (abs((acc_cal.y - acc_cal_pre.y)) > BMA250_SHAKING_DETECT_THRESHOLD) || (abs((acc_cal.z - acc_cal_pre.z)) > BMA250_SHAKING_DETECT_THRESHOLD)) ) { return count; } else { acc_cal_pre.x = acc_cal.x; acc_cal_pre.y = acc_cal.y; acc_cal_pre.z = acc_cal.z; } printk(KERN_INFO "wait 2ms and got cal ready flag is %d\n", tmp); timeout++; if (timeout == 1000) { printk(KERN_INFO "get fast calibration ready error\n"); return -EINVAL; } } while (tmp == 0); atomic_set(&bma250->fast_calib_x_rslt, 1); printk(KERN_INFO "z axis fast calibration finished\n"); return count; }
static void bma250_accl_getdata(struct drv_data *dd) { struct bma_acc_t acc; int X, Y, Z; struct bma250_accl_platform_data *pdata = pdata = bma250_accl_client->dev.platform_data; mutex_lock(&bma250_accl_wrk_lock); #ifndef BMA250_ACCL_IRQ_MODE if (!atomic_read(&bma_on)) { bma250_accl_power_up(dd); /* BMA250 need 2 to 3 ms delay */ /* to give valid data after wakeup */ msleep(2); } #endif bma250_read_accel_xyz(bma250_accl_client,&acc); switch (pdata->orientation) { case BMA_ROT_90: X = -acc.y; Y = acc.x; Z = acc.z; break; case BMA_ROT_180: X = -acc.x; Y = -acc.y; Z = acc.z; break; case BMA_ROT_270: X = acc.y; Y = -acc.x; Z = acc.z; break; default: pr_err("bma250_accl: invalid orientation specified\n"); case BMA_NO_ROT: X = acc.x; Y = acc.y; Z = acc.z; break; } if (pdata->invert) { } // printk("send to user[%d][%d][%d] \n",X, Y, Z); input_report_rel(dd->ip_dev, REL_X, X); input_report_rel(dd->ip_dev, REL_Y, Y); input_report_rel(dd->ip_dev, REL_Z, Z); input_sync(dd->ip_dev); newacc.x = X; newacc.y = Y; newacc.z = Z; #ifndef BMA250_ACCL_IRQ_MODE if (dd->bma250_accl_mode >= SENSOR_DELAY_UI) bma250_accl_power_down(dd); #endif mutex_unlock(&bma250_accl_wrk_lock); return; }