ssp_spi.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. /*
  2. * Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include "ssp.h"
  16. #define SSP_DEV (&data->spi->dev)
  17. #define SSP_GET_MESSAGE_TYPE(data) (data & (3 << SSP_RW))
  18. /*
  19. * SSP -> AP Instruction
  20. * They tell what packet type can be expected. In the future there will
  21. * be less of them. BYPASS means common sensor packets with accel, gyro,
  22. * hrm etc. data. LIBRARY and META are mock-up's for now.
  23. */
  24. #define SSP_MSG2AP_INST_BYPASS_DATA 0x37
  25. #define SSP_MSG2AP_INST_LIBRARY_DATA 0x01
  26. #define SSP_MSG2AP_INST_DEBUG_DATA 0x03
  27. #define SSP_MSG2AP_INST_BIG_DATA 0x04
  28. #define SSP_MSG2AP_INST_META_DATA 0x05
  29. #define SSP_MSG2AP_INST_TIME_SYNC 0x06
  30. #define SSP_MSG2AP_INST_RESET 0x07
  31. #define SSP_UNIMPLEMENTED -1
  32. struct ssp_msg_header {
  33. u8 cmd;
  34. __le16 length;
  35. __le16 options;
  36. __le32 data;
  37. } __attribute__((__packed__));
  38. struct ssp_msg {
  39. u16 length;
  40. u16 options;
  41. struct list_head list;
  42. struct completion *done;
  43. struct ssp_msg_header *h;
  44. char *buffer;
  45. };
  46. static const int ssp_offset_map[SSP_SENSOR_MAX] = {
  47. [SSP_ACCELEROMETER_SENSOR] = SSP_ACCELEROMETER_SIZE +
  48. SSP_TIME_SIZE,
  49. [SSP_GYROSCOPE_SENSOR] = SSP_GYROSCOPE_SIZE +
  50. SSP_TIME_SIZE,
  51. [SSP_GEOMAGNETIC_UNCALIB_SENSOR] = SSP_UNIMPLEMENTED,
  52. [SSP_GEOMAGNETIC_RAW] = SSP_UNIMPLEMENTED,
  53. [SSP_GEOMAGNETIC_SENSOR] = SSP_UNIMPLEMENTED,
  54. [SSP_PRESSURE_SENSOR] = SSP_UNIMPLEMENTED,
  55. [SSP_GESTURE_SENSOR] = SSP_UNIMPLEMENTED,
  56. [SSP_PROXIMITY_SENSOR] = SSP_UNIMPLEMENTED,
  57. [SSP_TEMPERATURE_HUMIDITY_SENSOR] = SSP_UNIMPLEMENTED,
  58. [SSP_LIGHT_SENSOR] = SSP_UNIMPLEMENTED,
  59. [SSP_PROXIMITY_RAW] = SSP_UNIMPLEMENTED,
  60. [SSP_ORIENTATION_SENSOR] = SSP_UNIMPLEMENTED,
  61. [SSP_STEP_DETECTOR] = SSP_UNIMPLEMENTED,
  62. [SSP_SIG_MOTION_SENSOR] = SSP_UNIMPLEMENTED,
  63. [SSP_GYRO_UNCALIB_SENSOR] = SSP_UNIMPLEMENTED,
  64. [SSP_GAME_ROTATION_VECTOR] = SSP_UNIMPLEMENTED,
  65. [SSP_ROTATION_VECTOR] = SSP_UNIMPLEMENTED,
  66. [SSP_STEP_COUNTER] = SSP_UNIMPLEMENTED,
  67. [SSP_BIO_HRM_RAW] = SSP_BIO_HRM_RAW_SIZE +
  68. SSP_TIME_SIZE,
  69. [SSP_BIO_HRM_RAW_FAC] = SSP_BIO_HRM_RAW_FAC_SIZE +
  70. SSP_TIME_SIZE,
  71. [SSP_BIO_HRM_LIB] = SSP_BIO_HRM_LIB_SIZE +
  72. SSP_TIME_SIZE,
  73. };
  74. #define SSP_HEADER_SIZE (sizeof(struct ssp_msg_header))
  75. #define SSP_HEADER_SIZE_ALIGNED (ALIGN(SSP_HEADER_SIZE, 4))
  76. static struct ssp_msg *ssp_create_msg(u8 cmd, u16 len, u16 opt, u32 data)
  77. {
  78. struct ssp_msg_header h;
  79. struct ssp_msg *msg;
  80. msg = kzalloc(sizeof(*msg), GFP_KERNEL);
  81. if (!msg)
  82. return NULL;
  83. h.cmd = cmd;
  84. h.length = cpu_to_le16(len);
  85. h.options = cpu_to_le16(opt);
  86. h.data = cpu_to_le32(data);
  87. msg->buffer = kzalloc(SSP_HEADER_SIZE_ALIGNED + len,
  88. GFP_KERNEL | GFP_DMA);
  89. if (!msg->buffer) {
  90. kfree(msg);
  91. return NULL;
  92. }
  93. msg->length = len;
  94. msg->options = opt;
  95. memcpy(msg->buffer, &h, SSP_HEADER_SIZE);
  96. return msg;
  97. }
  98. /*
  99. * It is a bit heavy to do it this way but often the function is used to compose
  100. * the message from smaller chunks which are placed on the stack. Often the
  101. * chunks are small so memcpy should be optimalized.
  102. */
  103. static inline void ssp_fill_buffer(struct ssp_msg *m, unsigned int offset,
  104. const void *src, unsigned int len)
  105. {
  106. memcpy(&m->buffer[SSP_HEADER_SIZE_ALIGNED + offset], src, len);
  107. }
  108. static inline void ssp_get_buffer(struct ssp_msg *m, unsigned int offset,
  109. void *dest, unsigned int len)
  110. {
  111. memcpy(dest, &m->buffer[SSP_HEADER_SIZE_ALIGNED + offset], len);
  112. }
  113. #define SSP_GET_BUFFER_AT_INDEX(m, index) \
  114. (m->buffer[SSP_HEADER_SIZE_ALIGNED + index])
  115. #define SSP_SET_BUFFER_AT_INDEX(m, index, val) \
  116. (m->buffer[SSP_HEADER_SIZE_ALIGNED + index] = val)
  117. static void ssp_clean_msg(struct ssp_msg *m)
  118. {
  119. kfree(m->buffer);
  120. kfree(m);
  121. }
  122. static int ssp_print_mcu_debug(char *data_frame, int *data_index,
  123. int received_len)
  124. {
  125. int length = data_frame[(*data_index)++];
  126. if (length > received_len - *data_index || length <= 0) {
  127. ssp_dbg("[SSP]: MSG From MCU-invalid debug length(%d/%d)\n",
  128. length, received_len);
  129. return length ? length : -EPROTO;
  130. }
  131. ssp_dbg("[SSP]: MSG From MCU - %s\n", &data_frame[*data_index]);
  132. *data_index += length;
  133. return 0;
  134. }
  135. /*
  136. * It was designed that way - additional lines to some kind of handshake,
  137. * please do not ask why - only the firmware guy can know it.
  138. */
  139. static int ssp_check_lines(struct ssp_data *data, bool state)
  140. {
  141. int delay_cnt = 0;
  142. gpio_set_value_cansleep(data->ap_mcu_gpio, state);
  143. while (gpio_get_value_cansleep(data->mcu_ap_gpio) != state) {
  144. usleep_range(3000, 3500);
  145. if (data->shut_down || delay_cnt++ > 500) {
  146. dev_err(SSP_DEV, "%s:timeout, hw ack wait fail %d\n",
  147. __func__, state);
  148. if (!state)
  149. gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
  150. return -ETIMEDOUT;
  151. }
  152. }
  153. return 0;
  154. }
  155. static int ssp_do_transfer(struct ssp_data *data, struct ssp_msg *msg,
  156. struct completion *done, int timeout)
  157. {
  158. int status;
  159. /*
  160. * check if this is a short one way message or the whole transfer has
  161. * second part after an interrupt
  162. */
  163. const bool use_no_irq = msg->length == 0;
  164. if (data->shut_down)
  165. return -EPERM;
  166. msg->done = done;
  167. mutex_lock(&data->comm_lock);
  168. status = ssp_check_lines(data, false);
  169. if (status < 0)
  170. goto _error_locked;
  171. status = spi_write(data->spi, msg->buffer, SSP_HEADER_SIZE);
  172. if (status < 0) {
  173. gpio_set_value_cansleep(data->ap_mcu_gpio, 1);
  174. dev_err(SSP_DEV, "%s spi_write fail\n", __func__);
  175. goto _error_locked;
  176. }
  177. if (!use_no_irq) {
  178. mutex_lock(&data->pending_lock);
  179. list_add_tail(&msg->list, &data->pending_list);
  180. mutex_unlock(&data->pending_lock);
  181. }
  182. status = ssp_check_lines(data, true);
  183. if (status < 0) {
  184. if (!use_no_irq) {
  185. mutex_lock(&data->pending_lock);
  186. list_del(&msg->list);
  187. mutex_unlock(&data->pending_lock);
  188. }
  189. goto _error_locked;
  190. }
  191. mutex_unlock(&data->comm_lock);
  192. if (!use_no_irq && done)
  193. if (wait_for_completion_timeout(done,
  194. msecs_to_jiffies(timeout)) ==
  195. 0) {
  196. mutex_lock(&data->pending_lock);
  197. list_del(&msg->list);
  198. mutex_unlock(&data->pending_lock);
  199. data->timeout_cnt++;
  200. return -ETIMEDOUT;
  201. }
  202. return 0;
  203. _error_locked:
  204. mutex_unlock(&data->comm_lock);
  205. data->timeout_cnt++;
  206. return status;
  207. }
  208. static inline int ssp_spi_sync_command(struct ssp_data *data,
  209. struct ssp_msg *msg)
  210. {
  211. return ssp_do_transfer(data, msg, NULL, 0);
  212. }
  213. static int ssp_spi_sync(struct ssp_data *data, struct ssp_msg *msg,
  214. int timeout)
  215. {
  216. DECLARE_COMPLETION_ONSTACK(done);
  217. if (WARN_ON(!msg->length))
  218. return -EPERM;
  219. return ssp_do_transfer(data, msg, &done, timeout);
  220. }
  221. static int ssp_handle_big_data(struct ssp_data *data, char *dataframe, int *idx)
  222. {
  223. /* mock-up, it will be changed with adding another sensor types */
  224. *idx += 8;
  225. return 0;
  226. }
  227. static int ssp_parse_dataframe(struct ssp_data *data, char *dataframe, int len)
  228. {
  229. int idx, sd;
  230. struct timespec ts;
  231. struct ssp_sensor_data *spd;
  232. struct iio_dev **indio_devs = data->sensor_devs;
  233. getnstimeofday(&ts);
  234. for (idx = 0; idx < len;) {
  235. switch (dataframe[idx++]) {
  236. case SSP_MSG2AP_INST_BYPASS_DATA:
  237. sd = dataframe[idx++];
  238. if (sd < 0 || sd >= SSP_SENSOR_MAX) {
  239. dev_err(SSP_DEV,
  240. "Mcu data frame1 error %d\n", sd);
  241. return -EPROTO;
  242. }
  243. if (indio_devs[sd]) {
  244. spd = iio_priv(indio_devs[sd]);
  245. if (spd->process_data)
  246. spd->process_data(indio_devs[sd],
  247. &dataframe[idx],
  248. data->timestamp);
  249. } else {
  250. dev_err(SSP_DEV, "no client for frame\n");
  251. }
  252. idx += ssp_offset_map[sd];
  253. break;
  254. case SSP_MSG2AP_INST_DEBUG_DATA:
  255. sd = ssp_print_mcu_debug(dataframe, &idx, len);
  256. if (sd) {
  257. dev_err(SSP_DEV,
  258. "Mcu data frame3 error %d\n", sd);
  259. return sd;
  260. }
  261. break;
  262. case SSP_MSG2AP_INST_LIBRARY_DATA:
  263. idx += len;
  264. break;
  265. case SSP_MSG2AP_INST_BIG_DATA:
  266. ssp_handle_big_data(data, dataframe, &idx);
  267. break;
  268. case SSP_MSG2AP_INST_TIME_SYNC:
  269. data->time_syncing = true;
  270. break;
  271. case SSP_MSG2AP_INST_RESET:
  272. ssp_queue_ssp_refresh_task(data, 0);
  273. break;
  274. }
  275. }
  276. if (data->time_syncing)
  277. data->timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
  278. return 0;
  279. }
  280. /* threaded irq */
  281. int ssp_irq_msg(struct ssp_data *data)
  282. {
  283. bool found = false;
  284. char *buffer;
  285. u8 msg_type;
  286. int ret;
  287. u16 length, msg_options;
  288. struct ssp_msg *msg, *n;
  289. ret = spi_read(data->spi, data->header_buffer, SSP_HEADER_BUFFER_SIZE);
  290. if (ret < 0) {
  291. dev_err(SSP_DEV, "header read fail\n");
  292. return ret;
  293. }
  294. length = le16_to_cpu(data->header_buffer[1]);
  295. msg_options = le16_to_cpu(data->header_buffer[0]);
  296. if (length == 0) {
  297. dev_err(SSP_DEV, "length received from mcu is 0\n");
  298. return -EINVAL;
  299. }
  300. msg_type = SSP_GET_MESSAGE_TYPE(msg_options);
  301. switch (msg_type) {
  302. case SSP_AP2HUB_READ:
  303. case SSP_AP2HUB_WRITE:
  304. /*
  305. * this is a small list, a few elements - the packets can be
  306. * received with no order
  307. */
  308. mutex_lock(&data->pending_lock);
  309. list_for_each_entry_safe(msg, n, &data->pending_list, list) {
  310. if (msg->options == msg_options) {
  311. list_del(&msg->list);
  312. found = true;
  313. break;
  314. }
  315. }
  316. if (!found) {
  317. /*
  318. * here can be implemented dead messages handling
  319. * but the slave should not send such ones - it is to
  320. * check but let's handle this
  321. */
  322. buffer = kmalloc(length, GFP_KERNEL | GFP_DMA);
  323. if (!buffer) {
  324. ret = -ENOMEM;
  325. goto _unlock;
  326. }
  327. /* got dead packet so it is always an error */
  328. ret = spi_read(data->spi, buffer, length);
  329. if (ret >= 0)
  330. ret = -EPROTO;
  331. kfree(buffer);
  332. dev_err(SSP_DEV, "No match error %x\n",
  333. msg_options);
  334. goto _unlock;
  335. }
  336. if (msg_type == SSP_AP2HUB_READ)
  337. ret = spi_read(data->spi,
  338. &msg->buffer[SSP_HEADER_SIZE_ALIGNED],
  339. msg->length);
  340. if (msg_type == SSP_AP2HUB_WRITE) {
  341. ret = spi_write(data->spi,
  342. &msg->buffer[SSP_HEADER_SIZE_ALIGNED],
  343. msg->length);
  344. if (msg_options & SSP_AP2HUB_RETURN) {
  345. msg->options =
  346. SSP_AP2HUB_READ | SSP_AP2HUB_RETURN;
  347. msg->length = 1;
  348. list_add_tail(&msg->list, &data->pending_list);
  349. goto _unlock;
  350. }
  351. }
  352. if (msg->done)
  353. if (!completion_done(msg->done))
  354. complete(msg->done);
  355. _unlock:
  356. mutex_unlock(&data->pending_lock);
  357. break;
  358. case SSP_HUB2AP_WRITE:
  359. buffer = kzalloc(length, GFP_KERNEL | GFP_DMA);
  360. if (!buffer)
  361. return -ENOMEM;
  362. ret = spi_read(data->spi, buffer, length);
  363. if (ret < 0) {
  364. dev_err(SSP_DEV, "spi read fail\n");
  365. kfree(buffer);
  366. break;
  367. }
  368. ret = ssp_parse_dataframe(data, buffer, length);
  369. kfree(buffer);
  370. break;
  371. default:
  372. dev_err(SSP_DEV, "unknown msg type\n");
  373. return -EPROTO;
  374. }
  375. return ret;
  376. }
  377. void ssp_clean_pending_list(struct ssp_data *data)
  378. {
  379. struct ssp_msg *msg, *n;
  380. mutex_lock(&data->pending_lock);
  381. list_for_each_entry_safe(msg, n, &data->pending_list, list) {
  382. list_del(&msg->list);
  383. if (msg->done)
  384. if (!completion_done(msg->done))
  385. complete(msg->done);
  386. }
  387. mutex_unlock(&data->pending_lock);
  388. }
  389. int ssp_command(struct ssp_data *data, char command, int arg)
  390. {
  391. int ret;
  392. struct ssp_msg *msg;
  393. msg = ssp_create_msg(command, 0, SSP_AP2HUB_WRITE, arg);
  394. if (!msg)
  395. return -ENOMEM;
  396. ssp_dbg("%s - command 0x%x %d\n", __func__, command, arg);
  397. ret = ssp_spi_sync_command(data, msg);
  398. ssp_clean_msg(msg);
  399. return ret;
  400. }
  401. int ssp_send_instruction(struct ssp_data *data, u8 inst, u8 sensor_type,
  402. u8 *send_buf, u8 length)
  403. {
  404. int ret;
  405. struct ssp_msg *msg;
  406. if (data->fw_dl_state == SSP_FW_DL_STATE_DOWNLOADING) {
  407. dev_err(SSP_DEV, "%s - Skip Inst! DL state = %d\n",
  408. __func__, data->fw_dl_state);
  409. return -EBUSY;
  410. } else if (!(data->available_sensors & BIT(sensor_type)) &&
  411. (inst <= SSP_MSG2SSP_INST_CHANGE_DELAY)) {
  412. dev_err(SSP_DEV, "%s - Bypass Inst Skip! - %u\n",
  413. __func__, sensor_type);
  414. return -EIO; /* just fail */
  415. }
  416. msg = ssp_create_msg(inst, length + 2, SSP_AP2HUB_WRITE, 0);
  417. if (!msg)
  418. return -ENOMEM;
  419. ssp_fill_buffer(msg, 0, &sensor_type, 1);
  420. ssp_fill_buffer(msg, 1, send_buf, length);
  421. ssp_dbg("%s - Inst = 0x%x, Sensor Type = 0x%x, data = %u\n",
  422. __func__, inst, sensor_type, send_buf[1]);
  423. ret = ssp_spi_sync(data, msg, 1000);
  424. ssp_clean_msg(msg);
  425. return ret;
  426. }
  427. int ssp_get_chipid(struct ssp_data *data)
  428. {
  429. int ret;
  430. char buffer;
  431. struct ssp_msg *msg;
  432. msg = ssp_create_msg(SSP_MSG2SSP_AP_WHOAMI, 1, SSP_AP2HUB_READ, 0);
  433. if (!msg)
  434. return -ENOMEM;
  435. ret = ssp_spi_sync(data, msg, 1000);
  436. buffer = SSP_GET_BUFFER_AT_INDEX(msg, 0);
  437. ssp_clean_msg(msg);
  438. return ret < 0 ? ret : buffer;
  439. }
  440. int ssp_set_magnetic_matrix(struct ssp_data *data)
  441. {
  442. int ret;
  443. struct ssp_msg *msg;
  444. msg = ssp_create_msg(SSP_MSG2SSP_AP_SET_MAGNETIC_STATIC_MATRIX,
  445. data->sensorhub_info->mag_length, SSP_AP2HUB_WRITE,
  446. 0);
  447. if (!msg)
  448. return -ENOMEM;
  449. ssp_fill_buffer(msg, 0, data->sensorhub_info->mag_table,
  450. data->sensorhub_info->mag_length);
  451. ret = ssp_spi_sync(data, msg, 1000);
  452. ssp_clean_msg(msg);
  453. return ret;
  454. }
  455. unsigned int ssp_get_sensor_scanning_info(struct ssp_data *data)
  456. {
  457. int ret;
  458. __le32 result;
  459. u32 cpu_result = 0;
  460. struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_SENSOR_SCANNING, 4,
  461. SSP_AP2HUB_READ, 0);
  462. if (!msg)
  463. return 0;
  464. ret = ssp_spi_sync(data, msg, 1000);
  465. if (ret < 0) {
  466. dev_err(SSP_DEV, "%s - spi read fail %d\n", __func__, ret);
  467. goto _exit;
  468. }
  469. ssp_get_buffer(msg, 0, &result, 4);
  470. cpu_result = le32_to_cpu(result);
  471. dev_info(SSP_DEV, "%s state: 0x%08x\n", __func__, cpu_result);
  472. _exit:
  473. ssp_clean_msg(msg);
  474. return cpu_result;
  475. }
  476. unsigned int ssp_get_firmware_rev(struct ssp_data *data)
  477. {
  478. int ret;
  479. __le32 result;
  480. struct ssp_msg *msg = ssp_create_msg(SSP_MSG2SSP_AP_FIRMWARE_REV, 4,
  481. SSP_AP2HUB_READ, 0);
  482. if (!msg)
  483. return SSP_INVALID_REVISION;
  484. ret = ssp_spi_sync(data, msg, 1000);
  485. if (ret < 0) {
  486. dev_err(SSP_DEV, "%s - transfer fail %d\n", __func__, ret);
  487. ret = SSP_INVALID_REVISION;
  488. goto _exit;
  489. }
  490. ssp_get_buffer(msg, 0, &result, 4);
  491. ret = le32_to_cpu(result);
  492. _exit:
  493. ssp_clean_msg(msg);
  494. return ret;
  495. }