static ssize_t bma250_calib_image_show(struct device *dev, struct device_attribute *attr, char *buf) { struct driver_data *dd = dev_get_drvdata(dev); int rc; /* enable EEPROM */ rc = bma250_ic_write(dd->ic_dev, BMA250_EEPROM_CTRL_REG, BMA250_EEPROM_PROG_MODE); if (rc) goto calib_offset_reg_error; /* get eeprom offset value */ rc = bma250_ic_read(dd->ic_dev, BMA250_OFFSET_X_AXIS_REG, buf, BMA250_CALIB_GET_REG_MAX); if (rc) goto calib_offset_reg_error; /* disable EEPROM */ rc = bma250_ic_write(dd->ic_dev, BMA250_EEPROM_CTRL_REG, BMA250_EEPROM_RDY_MODE); if (rc) goto calib_offset_reg_error; dev_dbg(&dd->ic_dev->dev, "%s:REG:%d:%d:%d\n", __func__, *buf, *(buf+1), *(buf+2)); return BMA250_CALIB_GET_REG_MAX; calib_offset_reg_error: dev_err(&dd->ic_dev->dev, "%s: Offset read/write error from register.\n", __func__); return -EIO; }
static inline int bma250_report_data(struct driver_data *dd) { int rc = 0; u8 rx_buf[7]; struct bma250_accel_data data; rc = bma250_ic_read(dd->ic_dev, BMA250_X_AXIS_LSB_REG, rx_buf, 7); if (rc) goto report_error; /* 10bit signed to 16bit signed */ data.accel_x = ((rx_buf[1] << 8) | (rx_buf[0] & 0xC0)); data.accel_y = ((rx_buf[3] << 8) | (rx_buf[2] & 0xC0)); data.accel_z = ((rx_buf[5] << 8) | (rx_buf[4] & 0xC0)); /* sensitivty 256lsb/g for all g-ranges */ data.accel_x = data.accel_x >> dd->shift; data.accel_y = data.accel_y >> dd->shift; data.accel_z = data.accel_z >> dd->shift; /* sensitivty 0.5C, center temprature 24C */ data.temp = (signed char)rx_buf[6] + 24*2; input_report_abs(dd->ip_dev, ABS_X, data.accel_x); input_report_abs(dd->ip_dev, ABS_Y, data.accel_y); input_report_abs(dd->ip_dev, ABS_Z, data.accel_z); input_report_abs(dd->ip_dev, ABS_MISC, data.temp); input_sync(dd->ip_dev); return rc; report_error: dev_err(&dd->ip_dev->dev, "%s: device failed, error %d\n", __func__, rc); return rc; }
static ssize_t bma250_dbfs_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos) { u8 rx; u8 mbuf[8]; int rc; int copy_size; struct driver_data *dd; dd = fp->private_data; if ((int)*f_pos > BMA250_LAST_REG) { rc = 0; goto dbfs_read_exit; } rc = bma250_ic_read(dd->ic_dev, (u8)*f_pos, &rx, 1); if (rc) goto dbfs_read_exit; snprintf(mbuf, ARRAY_SIZE(mbuf), "%02x %02x\n", (u8)*f_pos, rx); copy_size = min(count, strlen(mbuf) + 1); if (copy_to_user(buf, mbuf, copy_size)) return -EFAULT; (*f_pos)++; return copy_size; dbfs_read_exit: return rc; }
static int bma250_config(struct driver_data *dd) { int rc; u8 rx_buf[2]; const struct registers *preg = &use_chip_default; struct bma250_platform_data *pdata = dd->ic_dev->dev.platform_data; /* use platform data register values if they exist */ if (pdata && pdata->reg) preg = pdata->reg; rc = bma250_power_up(dd); if (rc) goto config_exit; rc = bma250_ic_read(dd->ic_dev, BMA250_CHIP_ID_REG, rx_buf, 2); if (rc) goto config_exit; if ((rx_buf[0] == 0x00) || (rx_buf[1] == 0x00)) { printk(KERN_ERR "bma250: device not found.\n"); rc = -ENODEV; goto config_exit; } printk(KERN_INFO "bma250: detected chip id %d, rev 0x%X\n", rx_buf[0] & 0x07, rx_buf[1]); if (preg->int_pin1 >= 0) { rc = bma250_ic_write(dd->ic_dev, BMA250_INT_PIN1_REG, preg->int_pin1); if (rc) goto config_exit; } if (preg->int_pin2 >= 0) { rc = bma250_ic_write(dd->ic_dev, BMA250_INT_PIN2_REG, preg->int_pin2); if (rc) goto config_exit; } rc = bma250_ic_write(dd->ic_dev, BMA250_INT_CTRL_REG, BMA250_INT_MODE_LATCHED); if (rc) goto config_exit; rc = bma250_update_settings(dd); config_exit: return rc; }
static int __devinit bma250_hwid(struct driver_data *dd) { int rc; u8 rx_buf[2]; rc = bma250_ic_read(dd->ic_dev, BMA250_CHIP_ID_REG, rx_buf, 2); if (rc) goto config_exit; if ((rx_buf[0] == 0x00) || (rx_buf[1] == 0x00)) { printk(KERN_ERR "bma250: device not found.\n"); rc = -ENODEV; goto config_exit; } printk(KERN_INFO "bma250: detected chip id %d, rev 0x%X\n", rx_buf[0] & 0x07, rx_buf[1]); config_exit: return rc; }
static inline int bma250_reset_interrupt(struct driver_data *dd) { int rc = 0; u8 val; if (dd->cur_cnf.resolution == INTERRUPT_RESOLUTION) { rc = bma250_ic_read(dd->ic_dev, BMA250_INT_CTRL_REG, &val, 1); if (rc) goto interrupt_error; rc = bma250_ic_write(dd->ic_dev, BMA250_INT_CTRL_REG, val | BMA250_INT_RESET); if (rc) goto interrupt_error; } return rc; interrupt_error: dev_err(&dd->ip_dev->dev, "%s: device failed, error %d\n", __func__, rc); return rc; }
static ssize_t bma250_calib_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { struct driver_data *dd = dev_get_drvdata(dev); int rc; /* read accel_data */ rc = bma250_ic_read(dd->ic_dev, BMA250_X_AXIS_LSB_REG, buf, BMA250_CALIB_GET_OFFSET_MAX); if (rc) goto calib_get_offset_error; dev_dbg(&dd->ic_dev->dev, "%s: offset: %d %d %d %d %d %d\n", __func__, *buf, *(buf + 1), *(buf + 2), *(buf + 3), *(buf + 4), *(buf + 5)); return BMA250_CALIB_GET_OFFSET_MAX; calib_get_offset_error: dev_err(&dd->ic_dev->dev, "%s: Data read error from register.(%d)\n", __func__, rc); return -EIO; }
static ssize_t bma250_calib_eeprom_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct driver_data *dd = dev_get_drvdata(dev); int rc; u8 tmp = 0; dev_dbg(&dd->ic_dev->dev, "%s : DEC : %d:%d:%d\n", __func__, *buf, *(buf + 1), *(buf + 2)); /* enable EEPROM */ rc = bma250_ic_write(dd->ic_dev, BMA250_EEPROM_CTRL_REG, BMA250_EEPROM_PROG_MODE); if (rc) goto calib_EEPROM_error; /* write X axis calibration data to Image (LSB) */ rc = bma250_ic_write(dd->ic_dev, BMA250_OFFSET_X_AXIS_REG, *buf); if (rc) goto calib_EEPROM_error; /* write Y axis calibration data to Image (LSB) */ rc = bma250_ic_write(dd->ic_dev, BMA250_OFFSET_Y_AXIS_REG, *(buf + 1)); if (rc) goto calib_EEPROM_error; /* write Z axis calibration data to Image (LSB) */ rc = bma250_ic_write(dd->ic_dev, BMA250_OFFSET_Z_AXIS_REG, *(buf + 2)); if (rc) goto calib_EEPROM_error; /* enable EEPROM write process */ rc = bma250_ic_write(dd->ic_dev, BMA250_EEPROM_CTRL_REG, BMA250_EEPROM_WRITE_MODE); if (rc) goto calib_EEPROM_error; msleep(BMA250_CALIB_SET_EEPROM); /* waiting for nvm_rdy bit is set*/ do { msleep(BMA250_CALIB_GET_INTERVAL); rc = bma250_ic_read(dd->ic_dev, BMA250_EEPROM_CTRL_REG, &tmp, 1); if (rc) goto calib_EEPROM_error; } while (!(tmp & BMA250_EEPROM_NOT_RDY_MODE)); /* disable data access to EEPROM area */ rc = bma250_ic_write(dd->ic_dev, BMA250_EEPROM_CTRL_REG, BMA250_EEPROM_RDY_MODE); if (rc) goto calib_EEPROM_error; msleep(BMA250_CALIB_SET_EEPROM); return BMA250_CALIB_GET_REG_MAX; calib_EEPROM_error: dev_err(&dd->ic_dev->dev, "%s: EEPROM read/write error from register.\n", __func__); return -EIO; }
static inline int bma250_report_data(struct driver_data *dd) { int rc = 0; u8 rx_buf[8]; char bypass = 0; int retrycount = 0; struct bma250_accel_data data; struct bma250_platform_data *pdata = dd->ic_dev->dev.platform_data; read_data_start: if (slave_hw) pdata->bypass_state(READ_BYPASS_STATE, &bypass); if (!slave_hw || !bypass) { /* Bypass mode */ FIFO_ACCESS_MUTEX_LOCK(); rc = bma250_ic_read(dd->ic_dev, BMA250_X_AXIS_LSB_REG, rx_buf, 7); FIFO_ACCESS_MUTEX_UNLOCK(); if (rc) { if (retrycount > BMA250_READDATA_RETRY) goto report_error; else { retrycount++; msleep(BMA250_BYPASS_STABEL); goto read_data_start; } } /* 10bit signed to 16bit signed */ data.accel_x = ((rx_buf[1] << 8) | (rx_buf[0] & 0xC0)); data.accel_y = ((rx_buf[3] << 8) | (rx_buf[2] & 0xC0)); data.accel_z = ((rx_buf[5] << 8) | (rx_buf[4] & 0xC0)); /* sensitivty 0.5C, center temprature 24C */ data.temp = (signed char)rx_buf[6] + 24*2; } else { /* Master mode */ FIFO_ACCESS_MUTEX_LOCK(); rc = pdata->read_axis_data(dd->ic_dev, &rx_buf[0], 6); FIFO_ACCESS_MUTEX_UNLOCK(); if (rc) { if (retrycount > BMA250_READDATA_RETRY) goto report_error; else { retrycount++; msleep(BMA250_BYPASS_STABEL); goto read_data_start; } } /* 10bit signed to 16bit signed */ data.accel_x = ((rx_buf[1] << 8) | (rx_buf[0] & 0xC0)); data.accel_y = ((rx_buf[3] << 8) | (rx_buf[2] & 0xC0)); data.accel_z = ((rx_buf[5] << 8) | (rx_buf[4] & 0xC0)); /* set defaults value. */ data.temp = 32*2; } /* sensitivty 256lsb/g for all g-ranges */ data.accel_x = data.accel_x >> dd->shift; data.accel_y = data.accel_y >> dd->shift; data.accel_z = data.accel_z >> dd->shift; input_report_abs(dd->ip_dev, ABS_X, data.accel_x); input_report_abs(dd->ip_dev, ABS_Y, data.accel_y); input_report_abs(dd->ip_dev, ABS_Z, data.accel_z); input_report_abs(dd->ip_dev, ABS_MISC, data.temp); input_sync(dd->ip_dev); return rc; report_error: printk(KERN_ERR "%s: Data read error from register.\n", __func__); return rc; }