123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811 |
- /*
- * 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 "ssp.h"
- #define LIMIT_DELAY_CNT 200
- #define RECEIVEBUFFERSIZE 12
- #define DEBUG_SHOW_DATA 0
- static void clean_msg(struct ssp_msg *msg) {
- if (msg->free_buffer)
- kfree(msg->buffer);
- kfree(msg);
- }
- static int do_transfer(struct ssp_data *data, struct ssp_msg *msg,
- struct completion *done, int timeout) {
- int status = 0;
- int iDelaycnt = 0;
- bool msg_dead = false, ssp_down = false;
- bool use_no_irq = msg->length == 0;
- msg->dead_hook = &msg_dead;
- msg->dead = false;
- msg->done = done;
- mutex_lock(&data->comm_mutex);
- gpio_set_value_cansleep(data->ap_int, 0);
- while (gpio_get_value_cansleep(data->mcu_int2)) {
- mdelay(3);
- if ((ssp_down = data->bSspShutdown) || iDelaycnt++ > 500) {
- pr_err("[SSP]: %s exit1 - Time out!!\n", __func__);
- gpio_set_value_cansleep(data->ap_int, 1);
- status = -1;
- goto exit;
- }
- }
- status = spi_write(data->spi, msg, 9) >= 0;
- if (status == 0) {
- pr_err("[SSP]: %s spi_write fail!!\n", __func__);
- gpio_set_value_cansleep(data->ap_int, 1);
- status = -1;
- goto exit;
- }
- if (!use_no_irq) {
- mutex_lock(&data->pending_mutex);
- list_add_tail(&msg->list, &data->pending_list);
- mutex_unlock(&data->pending_mutex);
- }
- iDelaycnt = 0;
- gpio_set_value_cansleep(data->ap_int, 1);
- while (!gpio_get_value_cansleep(data->mcu_int2)) {
- mdelay(3);
- if ((ssp_down = data->bSspShutdown) || iDelaycnt++ > 500) {
- pr_err("[SSP]: %s exit2 - Time out!!\n", __func__);
- status = -2;
- goto exit;
- }
- }
- exit:
- mutex_unlock(&data->comm_mutex);
- if (ssp_down)
- pr_err("[SSP] : %s, ssp down", __func__);
- if (status == -1) {
- data->uTimeOutCnt += ssp_down ? 0 : 1;
- clean_msg(msg);
- return status;
- }
- if (status == 1 && done != NULL)
- if (wait_for_completion_timeout(done, msecs_to_jiffies(timeout)) == 0)
- status = -2;
- mutex_lock(&data->pending_mutex);
- if (!msg_dead) {
- msg->done = NULL;
- msg->dead_hook = NULL;
- if (status != 1)
- msg->dead = true;
- if (status == -2)
- data->uTimeOutCnt += ssp_down ? 0 : 1;
- }
- mutex_unlock(&data->pending_mutex);
- if (use_no_irq)
- clean_msg(msg);
- return status;
- }
- int ssp_spi_async(struct ssp_data *data, struct ssp_msg *msg) {
- int status = 0;
- status = do_transfer(data, msg, NULL, 0);
- return status;
- }
- int ssp_spi_sync(struct ssp_data *data, struct ssp_msg *msg, int timeout) {
- DECLARE_COMPLETION_ONSTACK(done);
- int status = 0;
- if (msg->length == 0) {
- pr_err("[SSP]: %s length must not be 0\n", __func__);
- clean_msg(msg);
- return status;
- }
- status = do_transfer(data, msg, &done, timeout);
- return status;
- }
- int select_irq_msg(struct ssp_data *data) {
- struct ssp_msg *msg, *n;
- bool found = false;
- u16 chLength = 0, msg_options = 0;
- u8 msg_type = 0;
- int iRet = 0;
- char* buffer;
- char chTempBuf[4] = { -1 };
- iRet = spi_read(data->spi, chTempBuf, sizeof(chTempBuf));
- if (iRet < 0) {
- pr_err("[SSP]: %s spi_read fail!!\n", __func__);
- return ERROR;
- }
- memcpy(&msg_options, &chTempBuf[0], 2);
- msg_type = msg_options & SSP_SPI_MASK;
- memcpy(&chLength, &chTempBuf[2], 2);
- switch (msg_type) {
- case AP2HUB_READ:
- case AP2HUB_WRITE:
- mutex_lock(&data->pending_mutex);
- if (!list_empty(&data->pending_list)) {
- list_for_each_entry_safe(msg, n, &data->pending_list, list)
- {
- if (msg->options == msg_options) {
- list_del(&msg->list);
- found = true;
- break;
- }
- }
- if (!found) {
- pr_err("[SSP]: %s %d - Not match error\n", __func__, msg_options);
- goto exit;
- }
- if (msg->dead && !msg->free_buffer) {
- msg->buffer = (char*) kzalloc(msg->length, GFP_KERNEL);
- msg->free_buffer = 1;
- } // For dead msg, make a temporary buffer to read.
- if (msg_type == AP2HUB_READ)
- iRet = spi_read(data->spi, msg->buffer, msg->length);
- if (msg_type == AP2HUB_WRITE) {
- iRet = spi_write(data->spi, msg->buffer, msg->length);
- if (msg_options & AP2HUB_RETURN) {
- msg->options = AP2HUB_READ | AP2HUB_RETURN;
- msg->length = 1;
- list_add_tail(&msg->list, &data->pending_list);
- goto exit;
- }
- }
- if (msg->done != NULL && !completion_done(msg->done))
- complete(msg->done);
- if (msg->dead_hook != NULL)
- *(msg->dead_hook) = true;
- clean_msg(msg);
- } else
- pr_err("[SSP]List empty error(%d)\n", msg_type);
- exit:
- mutex_unlock(&data->pending_mutex);
- break;
- case HUB2AP_WRITE:
- buffer = (char*) kzalloc(chLength, GFP_KERNEL);
- if (buffer == NULL) {
- pr_err("[SSP] %s, failed to alloc memory for buffer\n", __func__);
- iRet = -ENOMEM;
- break;
- }
- iRet = spi_read(data->spi, buffer, chLength);
- parse_dataframe(data, buffer, chLength);
- kfree(buffer);
- break;
- default:
- pr_err("[SSP]No type error(%d)\n", msg_type);
- break;
- }
- if (iRet < 0) {
- pr_err("[SSP]: %s - MSG2SSP_SSD error %d\n", __func__, iRet);
- return ERROR;
- }
- return SUCCESS;
- }
- void clean_pending_list(struct ssp_data *data) {
- struct ssp_msg *msg, *n;
- mutex_lock(&data->pending_mutex);
- list_for_each_entry_safe(msg, n, &data->pending_list, list)
- {
- list_del(&msg->list);
- if (msg->done != NULL && !completion_done(msg->done))
- complete(msg->done);
- if (msg->dead_hook != NULL)
- *(msg->dead_hook) = true;
- clean_msg(msg);
- }
- mutex_unlock(&data->pending_mutex);
- }
- int ssp_send_cmd(struct ssp_data *data, char command, int arg)
- {
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = command;
- msg->length = 0;
- msg->options = AP2HUB_WRITE;
- msg->data = arg;
- msg->free_buffer = 0;
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - command 0x%x failed %d\n",
- __func__, command, iRet);
- return ERROR;
- }
- ssp_dbg("[SSP]: %s - command 0x%x %d\n", __func__, command, arg);
- return SUCCESS;
- }
- int send_instruction(struct ssp_data *data, u8 uInst,
- u8 uSensorType, u8 *uSendBuf, u8 uLength)
- {
- char command;
- int iRet = 0;
- struct ssp_msg *msg;
- if (data->fw_dl_state == FW_DL_STATE_DOWNLOADING) {
- pr_err("[SSP] %s - Skip Inst! DL state = %d\n",
- __func__, data->fw_dl_state);
- return SUCCESS;
- } else if ((!(data->uSensorState & (1 << uSensorType)))
- && (uInst <= CHANGE_DELAY)) {
- pr_err("[SSP]: %s - Bypass Inst Skip! - %u\n",
- __func__, uSensorType);
- return FAIL;
- }
- switch (uInst) {
- case REMOVE_SENSOR:
- command = MSG2SSP_INST_BYPASS_SENSOR_REMOVE;
- break;
- case ADD_SENSOR:
- command = MSG2SSP_INST_BYPASS_SENSOR_ADD;
- break;
- case CHANGE_DELAY:
- command = MSG2SSP_INST_CHANGE_DELAY;
- break;
- case GO_SLEEP:
- command = MSG2SSP_AP_STATUS_SLEEP;
- data->uLastAPState = MSG2SSP_AP_STATUS_SLEEP;
- break;
- case REMOVE_LIBRARY:
- command = MSG2SSP_INST_LIBRARY_REMOVE;
- break;
- case ADD_LIBRARY:
- command = MSG2SSP_INST_LIBRARY_ADD;
- break;
- default:
- command = uInst;
- break;
- }
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL) {
- pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
- iRet = -ENOMEM;
- return iRet;
- }
- if(uSensorType == GEOMAGNETIC_SENSOR)
- uLength += 1;
- msg->cmd = command;
- msg->length = uLength + 1;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(uLength + 1, GFP_KERNEL);
- msg->free_buffer = 1;
- msg->buffer[0] = uSensorType;
- memcpy(&msg->buffer[1], uSendBuf, uLength);
- if(uSensorType == GEOMAGNETIC_SENSOR) {
- msg->buffer[10] = MAG_LOG_MODE;
- }
- ssp_dbg("[SSP]: %s - Inst = 0x%x, Sensor Type = 0x%x, data = %u\n",
- __func__, command, uSensorType, msg->buffer[1]);
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Instruction CMD Fail %d\n", __func__, iRet);
- return ERROR;
- }
- return iRet;
- }
- int send_instruction_sync(struct ssp_data *data, u8 uInst,
- u8 uSensorType, u8 *uSendBuf, u8 uLength)
- {
- char command;
- int iRet = 0;
- char buffer[10] = { 0, };
- struct ssp_msg *msg;
- if (data->fw_dl_state == FW_DL_STATE_DOWNLOADING) {
- pr_err("[SSP] %s - Skip Inst! DL state = %d\n",
- __func__, data->fw_dl_state);
- return SUCCESS;
- } else if ((!(data->uSensorState & (1 << uSensorType)))
- && (uInst <= CHANGE_DELAY)) {
- pr_err("[SSP]: %s - Bypass Inst Skip! - %u\n",
- __func__, uSensorType);
- return FAIL;
- }
- switch (uInst) {
- case REMOVE_SENSOR:
- command = MSG2SSP_INST_BYPASS_SENSOR_REMOVE;
- break;
- case ADD_SENSOR:
- command = MSG2SSP_INST_BYPASS_SENSOR_ADD;
- break;
- case CHANGE_DELAY:
- command = MSG2SSP_INST_CHANGE_DELAY;
- break;
- case GO_SLEEP:
- command = MSG2SSP_AP_STATUS_SLEEP;
- data->uLastAPState = MSG2SSP_AP_STATUS_SLEEP;
- break;
- case REMOVE_LIBRARY:
- command = MSG2SSP_INST_LIBRARY_REMOVE;
- break;
- case ADD_LIBRARY:
- command = MSG2SSP_INST_LIBRARY_ADD;
- break;
- default:
- command = uInst;
- break;
- }
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = command;
- msg->length = uLength + 1;
- msg->options = AP2HUB_WRITE | AP2HUB_RETURN;
- msg->buffer = buffer;
- msg->free_buffer = 0;
- msg->buffer[0] = uSensorType;
- memcpy(&msg->buffer[1], uSendBuf, uLength);
- ssp_dbg("[SSP]: %s - Inst Sync = 0x%x, Sensor Type = %u, data = %u\n",
- __func__, command, uSensorType, msg->buffer[0]);
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - Instruction CMD Fail %d\n", __func__, iRet);
- return ERROR;
- }
- return buffer[0];
- }
- int flush(struct ssp_data *data, u8 uSensorType) {
- int iRet = 0;
- char buffer = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_MCU_BATCH_FLUSH;
- msg->length = 1;
- msg->options = AP2HUB_READ;
- msg->data = uSensorType;
- msg->buffer = &buffer;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - fail %d\n", __func__, iRet);
- return ERROR;
- }
- ssp_dbg("[SSP]: %s Sensor Type = 0x%x, data = %u\n", __func__, uSensorType,
- buffer);
- return buffer ? 0 : -1;
- }
- int get_batch_count(struct ssp_data *data, u8 uSensorType) {
- int iRet = 0;
- s32 result = 0;
- char buffer[4] = { 0, };
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_MCU_BATCH_COUNT;
- msg->length = 4;
- msg->options = AP2HUB_READ;
- msg->data = uSensorType;
- msg->buffer = buffer;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - fail %d\n", __func__, iRet);
- return ERROR;
- }
- memcpy(&result, buffer, 4);
- ssp_dbg("[SSP]: %s Sensor Type = 0x%x, data = %u\n", __func__, uSensorType,
- result);
- return result;
- }
- int get_chipid(struct ssp_data *data)
- {
- int iRet, iReties = 0;
- char buffer = 0;
- struct ssp_msg *msg;
- retries:
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL) {
- pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
- return -ENOMEM;
- }
- msg->cmd = MSG2SSP_AP_WHOAMI;
- msg->length = 1;
- msg->options = AP2HUB_READ;
- msg->buffer = &buffer;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (buffer != DEVICE_ID && iReties++ < 2) {
- mdelay(5);
- pr_err("[SSP] %s - get chip ID retry\n", __func__);
- goto retries;
- }
- if (iRet == SUCCESS)
- return buffer;
- pr_err("[SSP] %s - get chip ID failed %d\n", __func__, iRet);
- return ERROR;
- }
- int set_sensor_position(struct ssp_data *data)
- {
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_SENSOR_FORMATION;
- msg->length = 3;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(3, GFP_KERNEL);
- msg->free_buffer = 1;
- msg->buffer[0] = data->accel_position;
- msg->buffer[1] = data->accel_position;
- msg->buffer[2] = data->mag_position;
- pr_info("[SSP] Sensor Posision A : %u, G : %u, M: %u\n",
- data->accel_position, data->accel_position, data->mag_position);
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
- iRet = ERROR;
- }
- return iRet;
- }
- void set_proximity_threshold(struct ssp_data *data,
- unsigned int uData1, unsigned int uData2)
- {
- int iRet = 0;
- struct ssp_msg *msg;
- if (!(data->uSensorState & (1<<PROXIMITY_SENSOR))) {
- pr_info("[SSP]: %s - Skip this function!!!"\
- ", proximity sensor is not connected(0x%x)\n",
- __func__, data->uSensorState);
- return;
- }
- msg= kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_SENSOR_PROXTHRESHOLD;
- #if defined(CONFIG_SENSORS_SSP_STM_HESTIA)
- msg->length = 4;
- #else
- msg->length = 2;
- #endif
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(4, GFP_KERNEL);
- msg->free_buffer = 1;
- pr_err("[SSP]: %s - SENSOR_PROXTHRESHOL",__func__);
- //msg->buffer[0] = ((char) (uData1 >> 8) & 0x07);
- //msg->buffer[1] = (char) uData1;
- //msg->buffer[2] = ((char) (uData2 >> 8) & 0x07);
- //msg->buffer[3] = (char) uData2;
- uData1 += PROX_TRIM;
- uData2 += PROX_TRIM;
- if (uData1 < uData2) {
- pr_info("[SSP] %s - invalid threshold (%u, %u)\n",
- __func__, uData1, uData2);
- uData1 = DEFUALT_HIGH_THRESHOLD;
- uData2 = DEFUALT_LOW_THRESHOLD;
- }
- #if defined(CONFIG_SENSORS_SSP_STM_HESTIA)
- msg->buffer[0] = ((char) (uData1 >> 8) & 0x07);
- msg->buffer[1] = (char) uData1;
- msg->buffer[2] = ((char) (uData2 >> 8) & 0x07);
- msg->buffer[3] = (char) uData2;
- #else
- msg->buffer[0] = (char)uData1;
- msg->buffer[1] = (char)uData2;
- #endif
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - SENSOR_PROXTHRESHOLD CMD fail %d\n",
- __func__, iRet);
- return;
- }
- pr_info("[SSP]: Proximity Threshold - %u, %u\n", uData1, uData2);
- }
- void set_proximity_barcode_enable(struct ssp_data *data, bool bEnable)
- {
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_SENSOR_BARCODE_EMUL;
- msg->length = 1;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(1, GFP_KERNEL);
- msg->free_buffer = 1;
- data->bBarcodeEnabled = bEnable;
- msg->buffer[0] = bEnable;
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - SENSOR_BARCODE_EMUL CMD fail %d\n",
- __func__, iRet);
- return;
- }
- pr_info("[SSP] Proximity Barcode En : %u\n", bEnable);
- }
- void set_gesture_current(struct ssp_data *data, unsigned char uData1)
- {
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_SENSOR_GESTURE_CURRENT;
- msg->length = 1;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(1, GFP_KERNEL);
- msg->free_buffer = 1;
- msg->buffer[0] = uData1;
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - SENSOR_GESTURE_CURRENT CMD fail %d\n", __func__,
- iRet);
- return;
- }
- pr_info("[SSP]: Gesture Current Setting - %u\n", uData1);
- }
- unsigned int get_sensor_scanning_info(struct ssp_data *data) {
- int iRet = 0, z = 0;
- u32 result = 0;
- char bin[SENSOR_MAX + 1];
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- if (msg == NULL) {
- pr_err("[SSP] %s, failed to alloc memory for ssp_msg\n", __func__);
- return -ENOMEM;
- }
- msg->cmd = MSG2SSP_AP_SENSOR_SCANNING;
- msg->length = 4;
- msg->options = AP2HUB_READ;
- msg->buffer = (char*) &result;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS)
- pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
- bin[SENSOR_MAX] = '\0';
- for (z = 0; z < SENSOR_MAX; z++)
- bin[SENSOR_MAX - 1 - z] = (result & (1 << z)) ? '1' : '0';
- pr_err("[SSP]: state: %s\n", bin);
- return result;
- }
- unsigned int get_firmware_rev(struct ssp_data *data) {
- int iRet;
- u32 result = SSP_INVALID_REVISION;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_FIRMWARE_REV;
- msg->length = 4;
- msg->options = AP2HUB_READ;
- msg->buffer = (char*) &result;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS)
- pr_err("[SSP]: %s - transfer fail %d\n", __func__, iRet);
- return result;
- }
- int get_fuserom_data(struct ssp_data *data)
- {
- int iRet = 0;
- char buffer[3] = { 0, };
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_FUSEROM;
- msg->length = 3;
- msg->options = AP2HUB_READ;
- msg->buffer = buffer;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet) {
- data->uFuseRomData[0] = buffer[0];
- data->uFuseRomData[1] = buffer[1];
- data->uFuseRomData[2] = buffer[2];
- } else {
- data->uFuseRomData[0] = 0;
- data->uFuseRomData[1] = 0;
- data->uFuseRomData[2] = 0;
- return FAIL;
- }
- pr_info("[SSP] FUSE ROM Data %d , %d, %d\n", data->uFuseRomData[0],
- data->uFuseRomData[1], data->uFuseRomData[2]);
- return SUCCESS;
- }
- int set_big_data_start(struct ssp_data *data, u8 type, u32 length) {
- int iRet = 0;
- struct ssp_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_START_BIG_DATA;
- msg->length = 5;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(5, GFP_KERNEL);
- msg->free_buffer = 1;
- msg->buffer[0] = type;
- memcpy(&msg->buffer[1], &length, 4);
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
- iRet = ERROR;
- }
- return iRet;
- }
- int set_time(struct ssp_data *data) {
- int iRet;
- struct ssp_msg *msg;
- struct timespec ts;
- struct rtc_time tm;
- getnstimeofday(&ts);
- rtc_time_to_tm(ts.tv_sec, &tm);
- pr_info("[SSP]: %s %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
- tm.tm_sec, ts.tv_nsec);
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_MCU_SET_TIME;
- msg->length = 12;
- msg->options = AP2HUB_WRITE;
- msg->buffer = (char*) kzalloc(12, GFP_KERNEL);
- msg->free_buffer = 1;
- msg->buffer[0] = tm.tm_hour;
- msg->buffer[1] = tm.tm_min;
- msg->buffer[2] = tm.tm_sec;
- msg->buffer[3] = tm.tm_hour > 11 ? 64 : 0;
- msg->buffer[4] = tm.tm_wday;
- msg->buffer[5] = tm.tm_mon + 1;
- msg->buffer[6] = tm.tm_mday;
- msg->buffer[7] = tm.tm_year % 100;
- memcpy(&msg->buffer[8], &ts.tv_nsec, 4);
- iRet = ssp_spi_async(data, msg);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - i2c fail %d\n", __func__, iRet);
- iRet = ERROR;
- }
- return iRet;
- }
- int get_time(struct ssp_data *data) {
- int iRet;
- char buffer[12] = { 0, };
- struct ssp_msg *msg;
- struct timespec ts;
- struct rtc_time tm;
- getnstimeofday(&ts);
- rtc_time_to_tm(ts.tv_sec, &tm);
- pr_info("[SSP]: %s ap %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
- tm.tm_sec, ts.tv_nsec);
- msg = kzalloc(sizeof(*msg), GFP_KERNEL);
- msg->cmd = MSG2SSP_AP_MCU_GET_TIME;
- msg->length = 12;
- msg->options = AP2HUB_READ;
- msg->buffer = buffer;
- msg->free_buffer = 0;
- iRet = ssp_spi_sync(data, msg, 1000);
- if (iRet != SUCCESS) {
- pr_err("[SSP]: %s - i2c failed %d\n", __func__, iRet);
- return 0;
- }
- tm.tm_hour = buffer[0];
- tm.tm_min = buffer[1];
- tm.tm_sec = buffer[2];
- tm.tm_mon = msg->buffer[5] - 1;
- tm.tm_mday = buffer[6];
- tm.tm_year = buffer[7] + 100;
- rtc_tm_to_time(&tm, &ts.tv_sec);
- memcpy(&ts.tv_nsec, &msg->buffer[8], 4);
- rtc_time_to_tm(ts.tv_sec, &tm);
- pr_info("[SSP]: %s mcu %d-%02d-%02d %02d:%02d:%02d.%09lu UTC\n", __func__,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
- tm.tm_sec, ts.tv_nsec);
- return iRet;
- }
|