static int yas_acc_i2c_read(uint8_t slave, uint8_t adr, uint8_t *buf, int len) { struct yas_acc_private_data *data = yas_acc_get_data(); struct i2c_msg msg[2]; uint8_t reg; int err; reg = adr; msg[0].addr = slave; msg[0].flags = 0; msg[0].len = 1; msg[0].buf = ® msg[1].addr = slave; msg[1].flags = I2C_M_RD; msg[1].len = len; msg[1].buf = buf; err = i2c_transfer(data->client->adapter, msg, 2); if (err != 2) { printk(&data->client->dev, "i2c_transfer() read error: slave_addr=%02x, reg_addr=%02x, err=%d\n", slave, adr, err); return err; } return 0; }
static int yas_acc_set_enable(struct yas_acc_driver *driver, int enable) { struct yas_acc_private_data *data = yas_acc_get_data(); int delay = driver->get_delay(); dbg_func_in(); dbg("%s : enable=%d, delay=%d\n", __func__, enable, delay); #ifndef PANTECH_AVOID_DEADLOCK if (yas_acc_ischg_enable(driver, enable)) { #endif if (enable) { driver->set_enable(enable); schedule_delayed_work(&data->work, delay_to_jiffies(delay) + 1); dbg("%s : schedule_delayed_work(&data->work, %d)\n", __func__, delay); } else { cancel_delayed_work_sync(&data->work); dbg("%s : cancel_delayed_work_sync\n", __func__); driver->set_enable(enable); } #ifndef PANTECH_AVOID_DEADLOCK } #endif dbg_func_out(); return 0; }
static int yas_acc_i2c_write(uint8_t slave, uint8_t adr, const uint8_t *buf, int len) { struct yas_acc_private_data *data = yas_acc_get_data(); struct i2c_msg msg[2]; char buffer[16]; uint8_t reg; int err; int i; if (len > 15) { return -1; } reg = adr; buffer[0] = reg; for (i = 0; i < len; i++) { buffer[i+1] = buf[i]; } msg[0].addr = slave; msg[0].flags = 0; msg[0].len = len + 1; msg[0].buf = buffer; err = i2c_transfer(data->client->adapter, msg, 1); if (err != 1) { dev_err(&data->client->dev, "i2c_transfer() write error: slave_addr=%02x, reg_addr=%02x, err=%d\n", slave, adr, err); return err; } return 0; }
static int bma222_fast_calibration(char layout[]) { char tmp = 1; // select x axis in cal_trigger by default int power_off_after_calibration = 0; struct yas_acc_private_data *data =yas_acc_get_data(); if(!yas_bma222_get_enable()) { yas_bma222_power_up(); power_off_after_calibration = 1; } yas_bma222_update_bits(YAS_BMA222_COMP_TARGET_OFFSET_X, layout[0]); yas_bma222_update_bits(YAS_BMA222_EN_FAST_COMP, tmp); do { mdelay(2); tmp = yas_bma222_read_bits(YAS_BMA222_FAST_COMP_RDY_S); } while(tmp == 0); yas_bma222_update_bits(YAS_BMA222_COMP_TARGET_OFFSET_Y, layout[1]); tmp = 2; //selet y axis in cal_trigger yas_bma222_update_bits(YAS_BMA222_EN_FAST_COMP, tmp); do { mdelay(2); tmp = yas_bma222_read_bits( YAS_BMA222_FAST_COMP_RDY_S); } while(tmp == 0); yas_bma222_update_bits(YAS_BMA222_COMP_TARGET_OFFSET_Z, layout[2]); tmp = 3; //selet z axis in cal_trigger yas_bma222_update_bits(YAS_BMA222_EN_FAST_COMP, tmp); do { mdelay(2); tmp = yas_bma222_read_bits(YAS_BMA222_FAST_COMP_RDY_S); } while(tmp == 0); tmp = 1; //unlock eeprom yas_bma222_update_bits(YAS_BMA222_UNLOCK_EE_WRITE_SETTING, tmp); yas_bma222_update_bits(YAS_BMA222_START_EE_WRITE_SETTING, 0x01); do { mdelay(2); tmp = yas_bma222_read_bits(YAS_BMA222_EE_WRITE_SETTING_S); } while(tmp==0); tmp = 0; //lock eemprom yas_bma222_update_bits(YAS_BMA222_UNLOCK_EE_WRITE_SETTING, tmp); if(power_off_after_calibration) { yas_bma222_power_down(); } return 0; }
static int yas_acc_unlock(void) { struct yas_acc_private_data *data = yas_acc_get_data(); mutex_unlock(&data->driver_mutex); return 0; }
static int yas_acc_unlock(void) { #ifndef PANTECH_AVOID_DEADLOCK struct yas_acc_private_data *data = yas_acc_get_data(); mutex_unlock(&data->driver_mutex); #endif return 0; }
static int yas_acc_i2c_read(uint8_t slave, uint8_t reg, uint8_t *buf, int len) { OMAP_GPIO_I2C_RD_DATA i2c_rd_param; struct yas_acc_private_data *data = yas_acc_get_data(); i2c_rd_param.reg_addr = ® i2c_rd_param.reg_len = 1; i2c_rd_param.rdata_len = len; i2c_rd_param.rdata = buf; return omap_gpio_i2c_read(data->client, &i2c_rd_param); }
static int yas_acc_set_delay(struct yas_acc_driver *driver, int delay) { struct yas_acc_private_data *data = yas_acc_get_data(); if (driver->get_enable()) { cancel_delayed_work_sync(&data->work); driver->set_delay(actual_delay(delay)); schedule_delayed_work(&data->work, delay_to_jiffies(delay) + 1); } else { driver->set_delay(actual_delay(delay)); } return 0; }
static int yas_acc_set_enable(struct yas_acc_driver *driver, int enable) { struct yas_acc_private_data *data = yas_acc_get_data(); int delay = driver->get_delay(); if (yas_acc_ischg_enable(driver, enable)) { if (enable) { driver->set_enable(enable); schedule_delayed_work(&data->work, delay_to_jiffies(delay) + 1); } else { cancel_delayed_work_sync(&data->work); driver->set_enable(enable); } } return 0; }
static int accel_open_calibration(void) { struct file *cal_filp = NULL; int err = 0; mm_segment_t old_fs; struct yas_acc_private_data *data = yas_acc_get_data(); old_fs = get_fs(); set_fs(KERNEL_DS); cal_filp = filp_open(data->acc_pdata->cal_path, O_RDONLY, S_IRUGO | S_IWUSR | S_IWGRP); if (IS_ERR(cal_filp)) { set_fs(old_fs); err = PTR_ERR(cal_filp); return err; } err = cal_filp->f_op->read(cal_filp, #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) (char *)&data->cal_data, 3 * sizeof(s32), &cal_filp->f_pos); if (err != 3 * sizeof(s32)) { #else (char *)&data->cal_data, 3 * sizeof(s16), &cal_filp->f_pos); if (err != 3 * sizeof(s16)) { #endif pr_err("%s: Can't read the cal data from file\n", __func__); err = -EIO; } pr_info("%s: (%d,%d,%d)\n", __func__, data->cal_data.v[0], data->cal_data.v[1], data->cal_data.v[2]); #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) if (data->cal_data.v[0] == 0 && data->cal_data.v[1] == 0 && data->cal_data.v[2] == 0) data->calibrate = CAL_FAIL; else data->calibrate = CAL_SUCCESS; #endif filp_close(cal_filp, current->files); set_fs(old_fs); return err; }
static int bma222_exit_proc() { struct yas_acc_private_data *data = yas_acc_get_data(); struct yas_acc_driver *driver = data->driver; #if defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&data->early_suspend); #endif yas_acc_set_enable(driver, 0); sysfs_remove_group(&data->input->dev.kobj, &yas_acc_attribute_group); yas_acc_input_fini(data); yas_acc_core_driver_fini(data); kfree(data); return 0; }
static int yas_acc_set_delay(struct yas_acc_driver *driver, int delay) { #ifdef PANTECH_AVOID_DEADLOCK driver->set_delay(actual_delay(delay)); #else struct yas_acc_private_data *data = yas_acc_get_data(); if (driver->get_enable()) { cancel_delayed_work_sync(&data->work); driver->set_delay(actual_delay(delay)); schedule_delayed_work(&data->work, delay_to_jiffies(delay) + 1); } else { driver->set_delay(actual_delay(delay)); } #endif return 0; }
static int read_accel_raw_xyz(struct yas_vector *acc) { struct yas_acc_data accel; struct yas_acc_private_data *data = yas_acc_get_data(); mutex_lock(&data->data_mutex); yas_acc_measure(data->driver, &accel); mutex_unlock(&data->data_mutex); acc->v[0] = accel.xyz.v[0]; acc->v[1] = accel.xyz.v[1]; acc->v[2] = accel.xyz.v[2]; return 0; }
static int accel_do_calibrate(int enable) { struct file *cal_filp; int sum[3] = { 0, }; int err; int i; struct yas_vector raw; mm_segment_t old_fs; struct yas_acc_private_data *data = yas_acc_get_data(); mutex_lock(&data->data_mutex); yas_acc_set_enable_factory_test(data->driver, 1); mutex_unlock(&data->data_mutex); for (i = 0; i < 100; i++) { err = read_accel_raw_xyz(&raw); if (err < 0) { pr_err("%s: accel_read_accel_raw_xyz() " "failed in the %dth loop\n", __func__, i); return err; } sum[0] += raw.v[0]; sum[1] += raw.v[1]; sum[2] += raw.v[2]; } mutex_lock(&data->data_mutex); yas_acc_set_enable_factory_test(data->driver, 0); mutex_unlock(&data->data_mutex); if (enable) { data->cal_data.v[0] = (sum[0] / 100); data->cal_data.v[1] = (sum[1] / 100); data->cal_data.v[2] = #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) ((sum[2] / 100) - HAL_RESOLUTION); data->calibrate = CAL_SUCCESS; #else ((sum[2] / 100) - 256); #endif } else { data->cal_data.v[0] = 0; data->cal_data.v[1] = 0; data->cal_data.v[2] = 0; #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) data->calibrate = CAL_FAIL; #endif } pr_info("%s: cal data (%d,%d,%d)\n", __func__, data->cal_data.v[0], data->cal_data.v[1], data->cal_data.v[2]); old_fs = get_fs(); set_fs(KERNEL_DS); cal_filp = filp_open(data->acc_pdata->cal_path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUGO | S_IWUSR | S_IWGRP); if (IS_ERR(cal_filp)) { pr_err("%s: Can't open calibration file\n", __func__); set_fs(old_fs); err = PTR_ERR(cal_filp); return err; } err = cal_filp->f_op->write(cal_filp, #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) (char *)&data->cal_data, 3 * sizeof(s32), &cal_filp->f_pos); if (err != 3 * sizeof(s32)) { #else (char *)&data->cal_data, 3 * sizeof(s16), &cal_filp->f_pos); if (err != 3 * sizeof(s16)) { #endif pr_err("%s: Can't write the cal data to file\n", __func__); err = -EIO; #if (YAS_ACC_DRIVER == YAS_ACC_DRIVER_LIS3DH) data->calibrate = CAL_FAIL; #endif } filp_close(cal_filp, current->files); set_fs(old_fs); return err; }