static void bma255_set_enable(struct bma255_p *data, int enable) { int pre_enable = atomic_read(&data->enable); pr_info("\n bma255 sysfs set_enable sensor enable %d", enable); if (enable) { if (pre_enable == OFF) { bma255_open_calibration(data); bma255_set_mode(data->client, BMA255_MODE_NORMAL); schedule_delayed_work(&data->work, msecs_to_jiffies(atomic_read(&data->delay))); atomic_set(&data->enable, ON); //pr_info("bma255 enable =%d",data->enable); } } else { if (pre_enable == ON) { if (data->recog_flag == ON) bma255_set_mode(data->client, BMA255_MODE_LOWPOWER1); else bma255_set_mode(data->client, BMA255_MODE_SUSPEND); cancel_delayed_work_sync(&data->work); atomic_set(&data->enable, OFF); } } }
static ssize_t bma255_reactive_alert_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int enable = OFF, factory_mode = OFF; struct bma255_p *data = dev_get_drvdata(dev); if (sysfs_streq(buf, "0")) { enable = OFF; factory_mode = OFF; pr_info("[SENSOR]: %s - disable\n", __func__); } else if (sysfs_streq(buf, "1")) { enable = ON; factory_mode = OFF; pr_info("[SENSOR]: %s - enable\n", __func__); } else if (sysfs_streq(buf, "2")) { enable = ON; factory_mode = ON; pr_info("[SENSOR]: %s - factory mode\n", __func__); } else { pr_err("[SENSOR]: %s - invalid value %d\n", __func__, *buf); return -EINVAL; } if ((enable == ON) && (data->recog_flag == OFF)) { pr_info("[SENSOR]: %s - reactive alert is on!\n", __func__); data->irq_state = 0; bma255_slope_enable(data->client, ON, factory_mode); enable_irq(data->irq1); enable_irq_wake(data->irq1); if (atomic_read(&data->enable) == OFF) bma255_set_mode(data, BMA255_MODE_NORMAL); data->recog_flag = ON; } else if ((enable == OFF) && (data->recog_flag == ON)) { pr_info("[SENSOR]: %s - reactive alert is off! irq = %d\n", __func__, data->irq_state); bma255_slope_enable(data->client, OFF, factory_mode); disable_irq_wake(data->irq1); disable_irq_nosync(data->irq1); if (atomic_read(&data->enable) == OFF) bma255_set_mode(data, BMA255_MODE_SUSPEND); data->recog_flag = OFF; } return size; }
static int bma255_suspend(struct device *dev) { struct bma255_p *data = dev_get_drvdata(dev); if (atomic_read(&data->enable) == ON) { if (data->recog_flag == ON) bma255_set_mode(data, BMA255_MODE_NORMAL); else bma255_set_mode(data, BMA255_MODE_SUSPEND); cancel_delayed_work_sync(&data->work); } if (data->recog_flag == ON) disable_irq(data->irq1); return 0; }
static ssize_t bma255_raw_data_read(struct device *dev, struct device_attribute *attr, char *buf) { struct bma255_v acc; struct bma255_p *data = dev_get_drvdata(dev); //struct bma255_p *data = bma_acc_get_data(); if (atomic_read(&data->enable) == OFF) { bma255_set_mode(data->client, BMA255_MODE_NORMAL); msleep(20); bma255_read_accel_xyz(data, &acc); bma255_set_mode(data->client, BMA255_MODE_SUSPEND); acc.x = acc.x - data->caldata.x; acc.y = acc.y - data->caldata.y; acc.z = acc.z - data->caldata.z; } else { acc = data->accdata; } return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n", acc.x, acc.y, acc.z); }
static void bma255_set_enable(struct bma255_p *data, int enable) { int pre_enable = atomic_read(&data->enable); if (enable) { if (pre_enable == OFF) { bma255_open_calibration(data); bma255_set_mode(data, BMA255_MODE_NORMAL); schedule_delayed_work(&data->work, msecs_to_jiffies(atomic_read(&data->delay))); atomic_set(&data->enable, ON); } } else { if (pre_enable == ON) { if (data->recog_flag == ON) bma255_set_mode(data, BMA255_MODE_NORMAL); else bma255_set_mode(data, BMA255_MODE_SUSPEND); cancel_delayed_work_sync(&data->work); atomic_set(&data->enable, OFF); } } }
static int bma255_resume(struct device *dev) { struct bma255_p *data = dev_get_drvdata(dev); if (atomic_read(&data->enable) == ON) { bma255_set_mode(data, BMA255_MODE_NORMAL); schedule_delayed_work(&data->work, msecs_to_jiffies(atomic_read(&data->delay))); } if (data->recog_flag == ON) enable_irq(data->irq1); return 0; }
static int bma255_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV, i; struct bma255_p *data = NULL; pr_info("##########################################################\n"); pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct bma255_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } ret = bma255_parse_dt(data, client->dev.platform_data); if (ret < 0) { pr_err("[SENSOR]: %s - of_node error\n", __func__); ret = -ENODEV; goto exit_of_node; } ret = bma255_setup_pin(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup pin\n", __func__); goto exit_setup_pin; } i2c_set_clientdata(client, data); data->client = client; /* read chip id */ for (i = 0; i < CHIP_ID_RETRIES; i++) { ret = i2c_smbus_read_word_data(client, BMA255_CHIP_ID_REG); if ((ret & 0x00ff) != BMA255_CHIP_ID) { pr_err("[SENSOR]: %s - chip id failed %d\n", __func__, ret); } else { pr_info("[SENSOR]: %s - chip id success 0x%x\n", __func__, (unsigned int)ret & 0x00ff); break; } msleep(20); } if (i >= CHIP_ID_RETRIES) { ret = -ENODEV; goto exit_read_chipid; } /* input device init */ ret = bma255_input_init(data); if (ret < 0) goto exit_input_init; sensors_register(data->factory_device, data, sensor_attrs, MODULE_NAME); /* workqueue init */ INIT_DELAYED_WORK(&data->work, bma255_work_func); mutex_init(&data->mode_mutex); atomic_set(&data->delay, BMA255_DEFAULT_DELAY); atomic_set(&data->enable, OFF); data->time_count = 0; data->irq_state = 0; data->recog_flag = OFF; bma255_set_bandwidth(data->client, BMA255_BW_125HZ); bma255_set_range(data->client, BMA255_RANGE_2G); bma255_set_mode(data, BMA255_MODE_SUSPEND); pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n", __func__, data->chip_pos); return 0; exit_input_init: exit_read_chipid: free_irq(data->irq1, data); wake_lock_destroy(&data->reactive_wake_lock); gpio_free(data->acc_int2); gpio_free(data->acc_int1); exit_setup_pin: exit_of_node: kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; }
static int bma255_do_calibrate(struct bma255_p *data, int enable) { int sum[3] = { 0, }; int ret = 0, cnt; struct file *cal_filp = NULL; struct bma255_v acc; mm_segment_t old_fs; if (enable) { data->caldata.x = 0; data->caldata.y = 0; data->caldata.z = 0; if (atomic_read(&data->enable) == ON) cancel_delayed_work_sync(&data->work); else bma255_set_mode(data, BMA255_MODE_NORMAL); msleep(300); for (cnt = 0; cnt < CALIBRATION_DATA_AMOUNT; cnt++) { bma255_read_accel_xyz(data, &acc); sum[0] += acc.x; sum[1] += acc.y; sum[2] += acc.z; mdelay(10); } if (atomic_read(&data->enable) == ON) schedule_delayed_work(&data->work, msecs_to_jiffies(atomic_read(&data->delay))); else bma255_set_mode(data, BMA255_MODE_SUSPEND); data->caldata.x = (sum[0] / CALIBRATION_DATA_AMOUNT); data->caldata.y = (sum[1] / CALIBRATION_DATA_AMOUNT); data->caldata.z = (sum[2] / CALIBRATION_DATA_AMOUNT); if (data->caldata.z > 0) data->caldata.z -= MAX_ACCEL_1G; else if (data->caldata.z < 0) data->caldata.z += MAX_ACCEL_1G; } else { data->caldata.x = 0; data->caldata.y = 0; data->caldata.z = 0; } pr_info("[SENSOR]: %s - do accel calibrate %d, %d, %d\n", __func__, data->caldata.x, data->caldata.y, data->caldata.z); old_fs = get_fs(); set_fs(KERNEL_DS); cal_filp = filp_open(CALIBRATION_FILE_PATH, O_CREAT | O_TRUNC | O_WRONLY, 0666); if (IS_ERR(cal_filp)) { pr_err("[SENSOR]: %s - Can't open calibration file\n", __func__); set_fs(old_fs); ret = PTR_ERR(cal_filp); return ret; } ret = cal_filp->f_op->write(cal_filp, (char *)&data->caldata, 3 * sizeof(int), &cal_filp->f_pos); if (ret != 3 * sizeof(int)) { pr_err("[SENSOR]: %s - Can't write the caldata to file\n", __func__); ret = -EIO; } filp_close(cal_filp, current->files); set_fs(old_fs); return ret; }
static int bma255_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct bma255_p *data = NULL; pr_info("##########################################################\n"); pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct bma255_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } ret = bma255_parse_dt(data, &client->dev); if (ret < 0) { pr_err("[SENSOR]: %s - of_node error\n", __func__); ret = -ENODEV; goto exit_of_node; } /* read chip id */ ret = i2c_smbus_read_word_data(client, BMA255_CHIP_ID_REG); #if defined(CONFIG_MACH_CS03_SGLTE) if ((ret & 0x00ff) != 0x95) { #else if ((ret & 0x00ff) != BMA255_CHIP_ID) { #endif pr_err("[SENSOR]: %s - chip id failed %d\n", __func__, ret); ret = -ENODEV; goto exit_read_chipid; } i2c_set_clientdata(client, data); data->client = client; bma255_power_on(data, 1); ret = bma255_setup_pin(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup pin\n", __func__); goto exit_setup_pin; } /* input device init */ ret = bma255_input_init(data); if (ret < 0) goto exit_input_init; sensors_register(data->factory_device, data, sensor_attrs, MODULE_NAME); /* workqueue init */ INIT_DELAYED_WORK(&data->work, bma255_work_func); atomic_set(&data->delay, BMA255_DEFAULT_DELAY); atomic_set(&data->enable, OFF); data->time_count = 0; data->irq_state = 0; data->recog_flag = OFF; bma255_set_bandwidth(data->client, BMA255_BW_125HZ); bma255_set_range(data->client, BMA255_RANGE_2G); bma255_set_mode(data->client, BMA255_MODE_SUSPEND); pr_info("[SENSOR]: %s - Probe done!(chip pos : %d)\n", __func__, data->chip_pos); return 0; exit_input_init: free_irq(data->irq1, data); wake_lock_destroy(&data->reactive_wake_lock); gpio_free(data->acc_int2); gpio_free(data->acc_int1); exit_read_chipid: exit_setup_pin: exit_of_node: kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; } static int __devexit bma255_remove(struct i2c_client *client) { struct bma255_p *data = (struct bma255_p *)i2c_get_clientdata(client); if (atomic_read(&data->enable) == ON) bma255_set_enable(data, OFF); cancel_delayed_work_sync(&data->work); sensors_unregister(data->factory_device); //sensors_delete_symlink(data->input->dev); sysfs_remove_group(&data->input->dev.kobj, &bma255_attribute_group); input_unregister_device(data->input); free_irq(data->irq1, data); wake_lock_destroy(&data->reactive_wake_lock); gpio_free(data->acc_int2); gpio_free(data->acc_int1); kfree(data); return 0; } static int bma255_suspend(struct device *dev) { struct bma255_p *data = dev_get_drvdata(dev); //struct bma255_p *data = bma_acc_get_data(); if (atomic_read(&data->enable) == ON) { if (data->recog_flag == ON) bma255_set_mode(data->client, BMA255_MODE_LOWPOWER1); else bma255_set_mode(data->client, BMA255_MODE_SUSPEND); cancel_delayed_work_sync(&data->work); } bma255_power_on(data, 0); return 0; } static int bma255_resume(struct device *dev) { struct bma255_p *data = dev_get_drvdata(dev); //struct bma255_p *data = bma_acc_get_data(); bma255_power_on(data, 1); if (atomic_read(&data->enable) == ON) { bma255_set_mode(data->client, BMA255_MODE_NORMAL); schedule_delayed_work(&data->work, msecs_to_jiffies(atomic_read(&data->delay))); } return 0; } static struct of_device_id bma255_match_table[] = { { .compatible = "bma255-i2c",}, {}, };