123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713 |
- /*
- * Copyright (C) 2012, Samsung Electronics Co. Ltd. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
- #include <linux/kernel.h>
- #include "../ssp.h"
- /*************************************************************************/
- /* factory Sysfs */
- /*************************************************************************/
- #define VENDOR "INVENSENSE"
- #define CHIP_ID "MPU6500"
- #define VENDOR_K330 "STM"
- #define CHIP_ID_K330 "K330"
- #define CALIBRATION_FILE_PATH "/efs/gyro_cal_data"
- #define VERBOSE_OUT 1
- #define CALIBRATION_DATA_AMOUNT 20
- #define DEF_GYRO_FULLSCALE 2000
- #define DEF_GYRO_SENS (32768 / DEF_GYRO_FULLSCALE)
- #define DEF_BIAS_LSB_THRESH_SELF (20 * DEF_GYRO_SENS)
- #define DEF_BIAS_LSB_THRESH_SELF_6500 (30 * DEF_GYRO_SENS)
- #define DEF_RMS_LSB_TH_SELF (5 * DEF_GYRO_SENS)
- #define DEF_RMS_THRESH ((DEF_RMS_LSB_TH_SELF) * (DEF_RMS_LSB_TH_SELF))
- #define DEF_SCALE_FOR_FLOAT (1000)
- #define DEF_RMS_SCALE_FOR_RMS (10000)
- #define DEF_SQRT_SCALE_FOR_RMS (100)
- static ssize_t gyro_vendor_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- if (data->sns_combination == STM_K330_AG)
- return sprintf(buf, "%s\n", VENDOR_K330);
- else
- return sprintf(buf, "%s\n", VENDOR);
- }
- static ssize_t gyro_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- if (data->sns_combination == STM_K330_AG)
- return sprintf(buf, "%s\n", CHIP_ID_K330);
- else
- return sprintf(buf, "%s\n", CHIP_ID);
- }
- int gyro_open_calibration(struct ssp_data *data)
- {
- int iRet = 0;
- mm_segment_t old_fs;
- struct file *cal_filp = NULL;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
- if (IS_ERR(cal_filp)) {
- set_fs(old_fs);
- iRet = PTR_ERR(cal_filp);
- data->gyrocal.x = 0;
- data->gyrocal.y = 0;
- data->gyrocal.z = 0;
- return iRet;
- }
- iRet = cal_filp->f_op->read(cal_filp, (char *)&data->gyrocal,
- 3 * sizeof(int), &cal_filp->f_pos);
- if (iRet != 3 * sizeof(int))
- iRet = -EIO;
- filp_close(cal_filp, current->files);
- set_fs(old_fs);
- ssp_dbg("[SSP]: open gyro calibration %d, %d, %d\n",
- data->gyrocal.x, data->gyrocal.y, data->gyrocal.z);
- return iRet;
- }
- static int save_gyro_caldata(struct ssp_data *data, s16 *iCalData)
- {
- int iRet = 0;
- struct file *cal_filp = NULL;
- mm_segment_t old_fs;
- data->gyrocal.x = iCalData[0] << 2;
- data->gyrocal.y = iCalData[1] << 2;
- data->gyrocal.z = iCalData[2] << 2;
- ssp_dbg("[SSP]: do gyro calibrate %d, %d, %d\n",
- data->gyrocal.x, data->gyrocal.y, data->gyrocal.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("[SSP]: %s - Can't open calibration file\n", __func__);
- set_fs(old_fs);
- iRet = PTR_ERR(cal_filp);
- return -EIO;
- }
- iRet = cal_filp->f_op->write(cal_filp, (char *)&data->gyrocal,
- 3 * sizeof(int), &cal_filp->f_pos);
- if (iRet != 3 * sizeof(int)) {
- pr_err("[SSP]: %s - Can't write gyro cal to file\n", __func__);
- iRet = -EIO;
- }
- filp_close(cal_filp, current->files);
- set_fs(old_fs);
- return iRet;
- }
- int set_gyro_cal(struct ssp_data *data)
- {
- int iRet = 0;
- struct ssp_msg *msg;
- s16 gyro_cal[3];
- if (!(data->uSensorState & (1 << GYROSCOPE_SENSOR))) {
- pr_info("[SSP]: %s - Skip this function!!!"\
- ", gyro sensor is not connected(0x%x)\n",
- __func__, data->uSensorState);
- return iRet;
- }
- gyro_cal[0] = data->gyrocal.x;
- gyro_cal[1] = data->gyrocal.y;
- gyro_cal[2] = data->gyrocal.z;
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_MCU_SET_GYRO_CAL;
- msg->length = 6;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(6, GFP_KERNEL);
- msg->free_buffer = 1;
- memcpy(msg->buffer, gyro_cal, 6);
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
- iRet = ERROR;
- }
- pr_info("[SSP] Set gyro cal data %d, %d, %d\n", gyro_cal[0], gyro_cal[1], gyro_cal[2]);
- return iRet;
- }
- static ssize_t gyro_power_off(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- ssp_dbg("[SSP]: %s\n", __func__);
- return sprintf(buf, "%d\n", 1);
- }
- static ssize_t gyro_power_on(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- ssp_dbg("[SSP]: %s\n", __func__);
- return sprintf(buf, "%d\n", 1);
- }
- short mpu6500_gyro_get_temp(struct ssp_data *data)
- {
- char chTempBuf[2] = { 0};
- unsigned char reg[2];
- short temperature = 0;
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = GYROSCOPE_TEMP_FACTORY;
- msg->length = 2;
- msg->options = AP2HUB_READ;
- msg->buffer = chTempBuf;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 3000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Temp Timeout!!\n", __func__);
- goto exit;
- }
- reg[0] = chTempBuf[1];
- reg[1] = chTempBuf[0];
- temperature = (short) (((reg[0]) << 8) | reg[1]);
- ssp_dbg("[SSP]: %s - %d\n", __func__, temperature);
- exit:
- return temperature;
- }
- char k330_gyro_get_temp(struct ssp_data *data)
- {
- char chTemp = 0;
- int iRet = 0;
- struct ssp_msg *msg;
- if (!(data->uSensorState & (1 << GYROSCOPE_SENSOR)))
- goto exit;
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = GYROSCOPE_TEMP_FACTORY;
- msg->length = 1;
- msg->options = AP2HUB_READ;
- msg->buffer = &chTemp;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 3000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Temp Timeout!!\n", __func__);
- goto exit;
- }
- ssp_dbg("[SSP]: %s - %d\n", __func__, chTemp);
- exit:
- return chTemp;
- }
- static ssize_t gyro_get_temp(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- short temperature = 0;
- struct ssp_data *data = dev_get_drvdata(dev);
- if (data->sns_combination == STM_K330_AG)
- temperature = (short)k330_gyro_get_temp(data);
- else
- temperature = mpu6500_gyro_get_temp(data);
- return sprintf(buf, "%d\n", temperature);
- }
- u32 mpu6050_selftest_sqrt(u32 sqsum)
- {
- u32 sq_rt;
- u32 g0, g1, g2, g3, g4;
- u32 seed;
- u32 next;
- u32 step;
- g4 = sqsum / 100000000;
- g3 = (sqsum - g4 * 100000000) / 1000000;
- g2 = (sqsum - g4 * 100000000 - g3 * 1000000) / 10000;
- g1 = (sqsum - g4 * 100000000 - g3 * 1000000 - g2 * 10000) / 100;
- g0 = (sqsum - g4 * 100000000 - g3 * 1000000 - g2 * 10000 - g1 * 100);
- next = g4;
- step = 0;
- seed = 0;
- while (((seed + 1) * (step + 1)) <= next) {
- step++;
- seed++;
- }
- sq_rt = seed * 10000;
- next = (next - (seed * step)) * 100 + g3;
- step = 0;
- seed = 2 * seed * 10;
- while (((seed + 1) * (step + 1)) <= next) {
- step++;
- seed++;
- }
- sq_rt = sq_rt + step * 1000;
- next = (next - seed * step) * 100 + g2;
- seed = (seed + step) * 10;
- step = 0;
- while (((seed + 1) * (step + 1)) <= next) {
- step++;
- seed++;
- }
- sq_rt = sq_rt + step * 100;
- next = (next - seed * step) * 100 + g1;
- seed = (seed + step) * 10;
- step = 0;
- while (((seed + 1) * (step + 1)) <= next) {
- step++;
- seed++;
- }
- sq_rt = sq_rt + step * 10;
- next = (next - seed * step) * 100 + g0;
- seed = (seed + step) * 10;
- step = 0;
- while (((seed + 1) * (step + 1)) <= next) {
- step++;
- seed++;
- }
- sq_rt = sq_rt + step;
- return sq_rt;
- }
- ssize_t k330_gyro_selftest(char *buf, struct ssp_data *data)
- {
- char chTempBuf[36] = { 0,};
- u8 uFifoPass = 2;
- u8 uBypassPass = 2;
- u8 uCalPass = 0;
- u8 dummy[2] = {0,};
- s16 iNOST[3] = {0,}, iST[3] = {0,}, iCalData[3] = {0,};
- s16 iZeroRateData[3] = {0,}, fifo_data[4] = {0,};
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = GYROSCOPE_FACTORY;
- msg->length = 36;
- msg->options = AP2HUB_READ;
- msg->buffer = chTempBuf;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 5000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Selftest Timeout!!\n", __func__);
- goto exit;
- }
- data->uTimeOutCnt = 0;
- iNOST[0] = (s16)((chTempBuf[0] << 8) + chTempBuf[1]);
- iNOST[1] = (s16)((chTempBuf[2] << 8) + chTempBuf[3]);
- iNOST[2] = (s16)((chTempBuf[4] << 8) + chTempBuf[5]);
- iST[0] = (s16)((chTempBuf[6] << 8) + chTempBuf[7]);
- iST[1] = (s16)((chTempBuf[8] << 8) + chTempBuf[9]);
- iST[2] = (s16)((chTempBuf[10] << 8) + chTempBuf[11]);
- iCalData[0] = (s16)((chTempBuf[12] << 8) + chTempBuf[13]);
- iCalData[1] =( s16)((chTempBuf[14] << 8) + chTempBuf[15]);
- iCalData[2] = (s16)((chTempBuf[16] << 8) + chTempBuf[17]);
- iZeroRateData[0] = (s16)((chTempBuf[18] << 8) + chTempBuf[19]);
- iZeroRateData[1] = (s16)((chTempBuf[20] << 8) + chTempBuf[21]);
- iZeroRateData[2] = (s16)((chTempBuf[22] << 8) + chTempBuf[23]);
- fifo_data[0] = chTempBuf[24];
- fifo_data[1] = (s16)((chTempBuf[25] << 8) + chTempBuf[26]);
- fifo_data[2] = (s16)((chTempBuf[27] << 8) + chTempBuf[28]);
- fifo_data[3] = (s16)((chTempBuf[29] << 8) + chTempBuf[30]);
- uCalPass = chTempBuf[31];
- uFifoPass = chTempBuf[32];
- uBypassPass = chTempBuf[33];
- dummy[0] = chTempBuf[34];
- dummy[1] = chTempBuf[35];
- pr_info("[SSP] %s dummy = 0x%X, 0x%X\n", __func__, dummy[0], dummy[1]);
- if (uFifoPass && uBypassPass && uCalPass)
- save_gyro_caldata(data, iCalData);
- ssp_dbg("[SSP]: %s - %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
- __func__, iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
- iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
- fifo_data[0], fifo_data[1], fifo_data[2], fifo_data[3],
- uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
- exit:
- return sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
- iNOST[0], iNOST[1], iNOST[2], iST[0], iST[1], iST[2],
- iZeroRateData[0], iZeroRateData[1], iZeroRateData[2],
- fifo_data[0], fifo_data[1], fifo_data[2], fifo_data[3],
- uFifoPass & uBypassPass & uCalPass, uFifoPass, uCalPass);
- }
- ssize_t mpu6500_gyro_selftest(char *buf, struct ssp_data *data)
- {
- char chTempBuf[36] = { 0,};
- u8 initialized = 0;
- s8 hw_result = 0;
- int i = 0, j = 0, total_count = 0, ret_val = 0;
- long avg[3] = {0,}, rms[3] = {0,};
- int gyro_bias[3] = {0,}, gyro_rms[3] = {0,};
- s16 shift_ratio[3] = {0,};
- s16 iCalData[3] = {0,};
- char a_name[3][2] = { "X", "Y", "Z" };
- int iRet = 0;
- int dps_rms[3] = { 0, };
- u32 temp = 0;
- int bias_thresh = DEF_BIAS_LSB_THRESH_SELF_6500;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = GYROSCOPE_FACTORY;
- msg->length = 36;
- msg->options = AP2HUB_READ;
- msg->buffer = chTempBuf;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 7000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Selftest Timeout!!\n", __func__);
- ret_val = 1;
- goto exit;
- }
- data->uTimeOutCnt = 0;
- pr_err("[SSP]%d %d %d %d %d %d %d %d %d %d %d %d", chTempBuf[0], chTempBuf[1],
- chTempBuf[2], chTempBuf[3], chTempBuf[4], chTempBuf[5], chTempBuf[6],
- chTempBuf[7], chTempBuf[8], chTempBuf[9], chTempBuf[10], chTempBuf[11]);
- initialized = chTempBuf[0];
- shift_ratio[0] = (s16)((chTempBuf[2] << 8) +
- chTempBuf[1]);
- shift_ratio[1] = (s16)((chTempBuf[4] << 8) +
- chTempBuf[3]);
- shift_ratio[2] = (s16)((chTempBuf[6] << 8) +
- chTempBuf[5]);
- hw_result = (s8)chTempBuf[7];
- total_count = (int)((chTempBuf[11] << 24) +
- (chTempBuf[10] << 16) +
- (chTempBuf[9] << 8) +
- chTempBuf[8]);
- avg[0] = (long)((chTempBuf[15] << 24) +
- (chTempBuf[14] << 16) +
- (chTempBuf[13] << 8) +
- chTempBuf[12]);
- avg[1] = (long)((chTempBuf[19] << 24) +
- (chTempBuf[18] << 16) +
- (chTempBuf[17] << 8) +
- chTempBuf[16]);
- avg[2] = (long)((chTempBuf[23] << 24) +
- (chTempBuf[22] << 16) +
- (chTempBuf[21] << 8) +
- chTempBuf[20]);
- rms[0] = (long)((chTempBuf[27] << 24) +
- (chTempBuf[26] << 16) +
- (chTempBuf[25] << 8) +
- chTempBuf[24]);
- rms[1] = (long)((chTempBuf[31] << 24) +
- (chTempBuf[30] << 16) +
- (chTempBuf[29] << 8) +
- chTempBuf[28]);
- rms[2] = (long)((chTempBuf[35] << 24) +
- (chTempBuf[34] << 16) +
- (chTempBuf[33] << 8) +
- chTempBuf[32]);
- pr_info("[SSP] init: %d, total cnt: %d\n", initialized, total_count);
- pr_info("[SSP] hw_result: %d, %d, %d, %d\n", hw_result,
- shift_ratio[0], shift_ratio[1], shift_ratio[2]);
- pr_info("[SSP] avg %+8ld %+8ld %+8ld (LSB)\n", avg[0], avg[1], avg[2]);
- pr_info("[SSP] rms %+8ld %+8ld %+8ld (LSB)\n", rms[0], rms[1], rms[2]);
- if (hw_result < 0) {
- pr_err("[SSP] %s - hw selftest fail(%d), sw selftest skip\n",
- __func__, hw_result);
- return sprintf(buf, "-1,0,0,0,0,0,0,%d.%d,%d.%d,%d.%d,0,0,0\n",
- shift_ratio[0] / 10, shift_ratio[0] % 10,
- shift_ratio[1] / 10, shift_ratio[1] % 10,
- shift_ratio[2] / 10, shift_ratio[2] % 10);
- }
- gyro_bias[0] = (avg[0] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
- gyro_bias[1] = (avg[1] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
- gyro_bias[2] = (avg[2] * DEF_SCALE_FOR_FLOAT) / DEF_GYRO_SENS;
- iCalData[0] = (s16)avg[0];
- iCalData[1] = (s16)avg[1];
- iCalData[2] = (s16)avg[2];
- if (VERBOSE_OUT) {
- pr_info("[SSP] abs bias : %+8d.%03d %+8d.%03d %+8d.%03d (dps)\n",
- (int)abs(gyro_bias[0]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_bias[0]) % DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_bias[1]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_bias[1]) % DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_bias[2]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_bias[2]) % DEF_SCALE_FOR_FLOAT);
- }
- for (j = 0; j < 3; j++) {
- if (unlikely(abs(avg[j]) > bias_thresh)) {
- pr_err("[SSP] %s-Gyro bias (%ld) exceeded threshold "
- "(threshold = %d LSB)\n", a_name[j],
- avg[j], bias_thresh);
- ret_val |= 1 << (3 + j);
- }
- }
- /* 3rd, check RMS for dead gyros
- If any of the RMS noise value returns zero,
- then we might have dead gyro or FIFO/register failure,
- the part is sleeping, or the part is not responsive */
- if (rms[0] == 0 || rms[1] == 0 || rms[2] == 0)
- ret_val |= 1 << 6;
- if (VERBOSE_OUT) {
- pr_info("[SSP] RMS ^ 2 : %+8ld %+8ld %+8ld\n",
- (long)rms[0] / total_count,
- (long)rms[1] / total_count, (long)rms[2] / total_count);
- }
- for (j = 0; j < 3; j++) {
- if (unlikely(rms[j] / total_count > DEF_RMS_THRESH)) {
- pr_err("[SSP] %s-Gyro rms (%ld) exceeded threshold "
- "(threshold = %d LSB)\n", a_name[j],
- rms[j] / total_count, DEF_RMS_THRESH);
- ret_val |= 1 << (7 + j);
- }
- }
- for (i = 0; i < 3; i++) {
- if (rms[i] > 10000) {
- temp =
- ((u32) (rms[i] / total_count)) *
- DEF_RMS_SCALE_FOR_RMS;
- } else {
- temp =
- ((u32) (rms[i] * DEF_RMS_SCALE_FOR_RMS)) /
- total_count;
- }
- if (rms[i] < 0)
- temp = 1 << 31;
- dps_rms[i] = mpu6050_selftest_sqrt(temp) / DEF_GYRO_SENS;
- gyro_rms[i] =
- dps_rms[i] * DEF_SCALE_FOR_FLOAT / DEF_SQRT_SCALE_FOR_RMS;
- }
- pr_info("[SSP] RMS : %+8d.%03d %+8d.%03d %+8d.%03d (dps)\n",
- (int)abs(gyro_rms[0]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_rms[0]) % DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_rms[1]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_rms[1]) % DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_rms[2]) / DEF_SCALE_FOR_FLOAT,
- (int)abs(gyro_rms[2]) % DEF_SCALE_FOR_FLOAT);
- if (likely(!ret_val)) {
- save_gyro_caldata(data, iCalData);
- } else {
- pr_err("[SSP] ret_val != 0, gyrocal is 0 at all axis\n");
- data->gyrocal.x = 0;
- data->gyrocal.y = 0;
- data->gyrocal.z = 0;
- }
- exit:
- ssp_dbg("[SSP]: %s - %d,"
- "%d.%03d,%d.%03d,%d.%03d,"
- "%d.%03d,%d.%03d,%d.%03d,"
- "%d.%d,%d.%d,%d.%d,"
- "%d,%d,%d\n",
- __func__, ret_val,
- (int)abs(gyro_bias[0]/1000),
- (int)abs(gyro_bias[0])%1000,
- (int)abs(gyro_bias[1]/1000),
- (int)abs(gyro_bias[1])%1000,
- (int)abs(gyro_bias[2]/1000),
- (int)abs(gyro_bias[2])%1000,
- gyro_rms[0]/1000,
- (int)abs(gyro_rms[0])%1000,
- gyro_rms[1]/1000,
- (int)abs(gyro_rms[1])%1000,
- gyro_rms[2]/1000,
- (int)abs(gyro_rms[2])%1000,
- shift_ratio[0] / 10, shift_ratio[0] % 10,
- shift_ratio[1] / 10, shift_ratio[1] % 10,
- shift_ratio[2] / 10, shift_ratio[2] % 10,
- (int)(total_count/3),
- (int)(total_count/3),
- (int)(total_count/3));
- return sprintf(buf, "%d,"
- "%d.%03d,%d.%03d,%d.%03d,"
- "%d.%03d,%d.%03d,%d.%03d,"
- "%d.%d,%d.%d,%d.%d,"
- "%d,%d,%d\n",
- ret_val,
- (int)abs(gyro_bias[0]/1000),
- (int)abs(gyro_bias[0])%1000,
- (int)abs(gyro_bias[1]/1000),
- (int)abs(gyro_bias[1])%1000,
- (int)abs(gyro_bias[2]/1000),
- (int)abs(gyro_bias[2])%1000,
- gyro_rms[0]/1000,
- (int)abs(gyro_rms[0])%1000,
- gyro_rms[1]/1000,
- (int)abs(gyro_rms[1])%1000,
- gyro_rms[2]/1000,
- (int)abs(gyro_rms[2])%1000,
- shift_ratio[0] / 10, shift_ratio[0] % 10,
- shift_ratio[1] / 10, shift_ratio[1] % 10,
- shift_ratio[2] / 10, shift_ratio[2] % 10,
- (int)(total_count/3),
- (int)(total_count/3),
- (int)(total_count/3));
- }
- static ssize_t gyro_selftest_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- if (data->sns_combination == STM_K330_AG)
- return k330_gyro_selftest(buf, data);
- else
- return mpu6500_gyro_selftest(buf, data);
- }
- static ssize_t gyro_selftest_dps_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
- {
- int iNewDps = 0;
- int iRet = 0;
- char chTempBuf = 0;
- struct ssp_data *data = dev_get_drvdata(dev);
- struct ssp_msg *msg;
- if (!(data->uSensorState & (1 << GYROSCOPE_SENSOR)))
- goto exit;
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = GYROSCOPE_DPS_FACTORY;
- msg->length = 1;
- msg->options = AP2HUB_READ;
- msg->buffer = &chTempBuf;
- msg->free_buffer = 0;
- sscanf(buf, "%d", &iNewDps);
- if (iNewDps == GYROSCOPE_DPS250)
- msg->options |= 0 << SSP_GYRO_DPS;
- else if (iNewDps == GYROSCOPE_DPS500)
- msg->options |= 1 << SSP_GYRO_DPS;
- else if (iNewDps == GYROSCOPE_DPS2000)
- msg->options |= 2 << SSP_GYRO_DPS;
- else {
- msg->options |= 1 << SSP_GYRO_DPS;
- iNewDps = GYROSCOPE_DPS500;
- }
- iRet = ssp_spi_sync(data, msg, 3000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Selftest DPS Timeout!!\n", __func__);
- goto exit;
- }
- if (chTempBuf != SUCCESS) {
- pr_err("[SSP]: %s - Gyro Selftest DPS Error!!\n", __func__);
- goto exit;
- }
- data->uGyroDps = (unsigned int)iNewDps;
- pr_err("[SSP]: %s - %u dps stored\n", __func__, data->uGyroDps);
- exit:
- return count;
- }
- static ssize_t gyro_selftest_dps_show(struct device *dev,
- struct device_attribute *attr, char *buf)
- {
- struct ssp_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%u\n", data->uGyroDps);
- }
- static DEVICE_ATTR(name, S_IRUGO, gyro_name_show, NULL);
- static DEVICE_ATTR(vendor, S_IRUGO, gyro_vendor_show, NULL);
- static DEVICE_ATTR(power_off, S_IRUGO, gyro_power_off, NULL);
- static DEVICE_ATTR(power_on, S_IRUGO, gyro_power_on, NULL);
- static DEVICE_ATTR(temperature, S_IRUGO, gyro_get_temp, NULL);
- static DEVICE_ATTR(selftest, S_IRUSR|S_IRGRP, gyro_selftest_show, NULL);
- static DEVICE_ATTR(selftest_dps, S_IRUGO | S_IWUSR | S_IWGRP,
- gyro_selftest_dps_show, gyro_selftest_dps_store);
- static struct device_attribute *gyro_attrs[] = {
- &dev_attr_name,
- &dev_attr_vendor,
- &dev_attr_selftest,
- &dev_attr_power_on,
- &dev_attr_power_off,
- &dev_attr_temperature,
- &dev_attr_selftest_dps,
- NULL,
- };
- void initialize_gyro_factorytest(struct ssp_data *data)
- {
- sensors_register(data->gyro_device, data, gyro_attrs, "gyro_sensor");
- }
- void remove_gyro_factorytest(struct ssp_data *data)
- {
- sensors_unregister(data->gyro_device, gyro_attrs);
- }
|