prox_cm36651.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * Copyright (C) 2012, 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 VENDOR "CAPELLA"
  17. #define CHIP_ID "CM36651"
  18. #define CANCELATION_FILE_PATH "/efs/prox_cal"
  19. /*************************************************************************/
  20. /* factory Sysfs */
  21. /*************************************************************************/
  22. static ssize_t prox_vendor_show(struct device *dev,
  23. struct device_attribute *attr, char *buf)
  24. {
  25. return sprintf(buf, "%s\n", VENDOR);
  26. }
  27. static ssize_t prox_name_show(struct device *dev,
  28. struct device_attribute *attr, char *buf)
  29. {
  30. return sprintf(buf, "%s\n", CHIP_ID);
  31. }
  32. static ssize_t proximity_avg_show(struct device *dev,
  33. struct device_attribute *attr, char *buf)
  34. {
  35. struct ssp_data *data = dev_get_drvdata(dev);
  36. return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n",
  37. data->buf[PROXIMITY_RAW].prox[1],
  38. data->buf[PROXIMITY_RAW].prox[2],
  39. data->buf[PROXIMITY_RAW].prox[3]);
  40. }
  41. static ssize_t proximity_avg_store(struct device *dev,
  42. struct device_attribute *attr, const char *buf, size_t size)
  43. {
  44. char chTempbuf[2] = { 1, 20};
  45. int iRet;
  46. int64_t dEnable;
  47. struct ssp_data *data = dev_get_drvdata(dev);
  48. iRet = strict_strtoll(buf, 10, &dEnable);
  49. if (iRet < 0)
  50. return iRet;
  51. if (dEnable) {
  52. send_instruction(data, ADD_SENSOR, PROXIMITY_RAW, chTempbuf, 2);
  53. data->bProximityRawEnabled = true;
  54. } else {
  55. send_instruction(data, REMOVE_SENSOR, PROXIMITY_RAW,
  56. chTempbuf, 2);
  57. data->bProximityRawEnabled = false;
  58. }
  59. return size;
  60. }
  61. static unsigned char get_proximity_rawdata(struct ssp_data *data)
  62. {
  63. unsigned char uRowdata = 0;
  64. char chTempbuf[2] = { 1, 20};
  65. if (data->bProximityRawEnabled == false) {
  66. send_instruction(data, ADD_SENSOR, PROXIMITY_RAW, chTempbuf, 2);
  67. msleep(200);
  68. uRowdata = data->buf[PROXIMITY_RAW].prox[0];
  69. send_instruction(data, REMOVE_SENSOR, PROXIMITY_RAW,
  70. chTempbuf, 2);
  71. } else {
  72. uRowdata = data->buf[PROXIMITY_RAW].prox[0];
  73. }
  74. return uRowdata;
  75. }
  76. static ssize_t proximity_state_show(struct device *dev,
  77. struct device_attribute *attr, char *buf)
  78. {
  79. struct ssp_data *data = dev_get_drvdata(dev);
  80. return sprintf(buf, "%u\n", get_proximity_rawdata(data));
  81. }
  82. int proximity_open_calibration(struct ssp_data *data)
  83. {
  84. int iRet = 0;
  85. mm_segment_t old_fs;
  86. struct file *cancel_filp = NULL;
  87. old_fs = get_fs();
  88. set_fs(KERNEL_DS);
  89. cancel_filp = filp_open(CANCELATION_FILE_PATH, O_RDONLY, 0666);
  90. if (IS_ERR(cancel_filp)) {
  91. iRet = PTR_ERR(cancel_filp);
  92. if (iRet != -ENOENT)
  93. pr_err("[SSP]: %s - Can't open cancelation file\n",
  94. __func__);
  95. set_fs(old_fs);
  96. goto exit;
  97. }
  98. iRet = cancel_filp->f_op->read(cancel_filp,
  99. (u8 *)&data->uProxCanc, sizeof(u8), &cancel_filp->f_pos);
  100. if (iRet != sizeof(u8)) {
  101. pr_err("[SSP]: %s - Can't read the cancel data\n", __func__);
  102. iRet = -EIO;
  103. }
  104. if (data->uProxCanc != 0) /*If there is an offset cal data. */
  105. data->uProxThresh = CANCELATION_THRESHOLD;
  106. pr_info("%s: proximity ps_canc = %d, ps_thresh = %d\n",
  107. __func__, data->uProxCanc, data->uProxThresh);
  108. filp_close(cancel_filp, current->files);
  109. set_fs(old_fs);
  110. exit:
  111. set_proximity_threshold(data);
  112. return iRet;
  113. }
  114. static int proximity_store_cancelation(struct ssp_data *data, int iCalCMD)
  115. {
  116. int iRet = 0;
  117. mm_segment_t old_fs;
  118. struct file *cancel_filp = NULL;
  119. if (iCalCMD) {
  120. data->uProxThresh = CANCELATION_THRESHOLD;
  121. data->uProxCanc = get_proximity_rawdata(data);
  122. } else {
  123. data->uProxThresh = DEFUALT_THRESHOLD;
  124. data->uProxCanc = 0;
  125. }
  126. set_proximity_threshold(data);
  127. old_fs = get_fs();
  128. set_fs(KERNEL_DS);
  129. cancel_filp = filp_open(CANCELATION_FILE_PATH,
  130. O_CREAT | O_TRUNC | O_WRONLY, 0666);
  131. if (IS_ERR(cancel_filp)) {
  132. pr_err("%s: Can't open cancelation file\n", __func__);
  133. set_fs(old_fs);
  134. iRet = PTR_ERR(cancel_filp);
  135. return iRet;
  136. }
  137. iRet = cancel_filp->f_op->write(cancel_filp, (u8 *)&data->uProxCanc,
  138. sizeof(u8), &cancel_filp->f_pos);
  139. if (iRet != sizeof(u8)) {
  140. pr_err("%s: Can't write the cancel data to file\n", __func__);
  141. iRet = -EIO;
  142. }
  143. filp_close(cancel_filp, current->files);
  144. set_fs(old_fs);
  145. return iRet;
  146. }
  147. static ssize_t proximity_cancel_show(struct device *dev,
  148. struct device_attribute *attr, char *buf)
  149. {
  150. struct ssp_data *data = dev_get_drvdata(dev);
  151. ssp_dbg("[SSP]: uProxThresh = %u, uProxCanc = %u\n",
  152. data->uProxThresh, data->uProxCanc);
  153. return sprintf(buf, "%u,%u\n", data->uProxCanc, data->uProxThresh);
  154. }
  155. static ssize_t proximity_cancel_store(struct device *dev,
  156. struct device_attribute *attr, const char *buf, size_t size)
  157. {
  158. int iCalCMD = 0, iRet = 0;
  159. struct ssp_data *data = dev_get_drvdata(dev);
  160. if (sysfs_streq(buf, "1")) /* calibrate cancelation value */
  161. iCalCMD = 1;
  162. else if (sysfs_streq(buf, "0")) /* reset cancelation value */
  163. iCalCMD = 0;
  164. else {
  165. pr_debug("%s: invalid value %d\n", __func__, *buf);
  166. return -EINVAL;
  167. }
  168. iRet = proximity_store_cancelation(data, iCalCMD);
  169. if (iRet < 0) {
  170. pr_err("[SSP]: - %s proximity_store_cancelation() failed\n",
  171. __func__);
  172. return iRet;
  173. }
  174. ssp_dbg("[SSP]: %s - %u\n", __func__, iCalCMD);
  175. return size;
  176. }
  177. static ssize_t proximity_thresh_show(struct device *dev,
  178. struct device_attribute *attr, char *buf)
  179. {
  180. struct ssp_data *data = dev_get_drvdata(dev);
  181. ssp_dbg("[SSP]: uProxThresh = %u\n", data->uProxThresh);
  182. return sprintf(buf, "%u\n", data->uProxThresh);
  183. }
  184. static ssize_t proximity_thresh_store(struct device *dev,
  185. struct device_attribute *attr, const char *buf, size_t size)
  186. {
  187. struct ssp_data *data = dev_get_drvdata(dev);
  188. u8 uNewThresh = 0x09;
  189. int iRet = 0;
  190. iRet = kstrtou8(buf, 10, &uNewThresh);
  191. if (iRet < 0)
  192. pr_err("[SSP]: %s - kstrtoint failed.", __func__);
  193. data->uProxThresh = uNewThresh;
  194. set_proximity_threshold(data);
  195. ssp_dbg("[SSP]: %s - new prox threshold = 0x%x\n",
  196. __func__, data->uProxThresh);
  197. return size;
  198. }
  199. static ssize_t barcode_emul_enable_show(struct device *dev,
  200. struct device_attribute *attr, char *buf)
  201. {
  202. struct ssp_data *data = dev_get_drvdata(dev);
  203. return snprintf(buf, PAGE_SIZE, "%u\n", data->bBarcodeEnabled);
  204. }
  205. static ssize_t barcode_emul_enable_store(struct device *dev,
  206. struct device_attribute *attr, const char *buf, size_t size)
  207. {
  208. int iRet;
  209. int64_t dEnable;
  210. struct ssp_data *data = dev_get_drvdata(dev);
  211. iRet = strict_strtoll(buf, 10, &dEnable);
  212. if (iRet < 0)
  213. return iRet;
  214. if (dEnable)
  215. set_proximity_barcode_enable(data, true);
  216. else
  217. set_proximity_barcode_enable(data, false);
  218. return size;
  219. }
  220. static DEVICE_ATTR(vendor, S_IRUGO, prox_vendor_show, NULL);
  221. static DEVICE_ATTR(name, S_IRUGO, prox_name_show, NULL);
  222. static DEVICE_ATTR(state, S_IRUGO, proximity_state_show, NULL);
  223. static DEVICE_ATTR(barcode_emul_en, S_IRUGO | S_IWUSR | S_IWGRP,
  224. barcode_emul_enable_show, barcode_emul_enable_store);
  225. static DEVICE_ATTR(prox_avg, S_IRUGO | S_IWUSR | S_IWGRP,
  226. proximity_avg_show, proximity_avg_store);
  227. static DEVICE_ATTR(prox_cal, S_IRUGO | S_IWUSR | S_IWGRP,
  228. proximity_cancel_show, proximity_cancel_store);
  229. static DEVICE_ATTR(prox_thresh, S_IRUGO | S_IWUSR | S_IWGRP,
  230. proximity_thresh_show, proximity_thresh_store);
  231. static struct device_attribute *prox_attrs[] = {
  232. &dev_attr_vendor,
  233. &dev_attr_name,
  234. &dev_attr_state,
  235. &dev_attr_prox_avg,
  236. &dev_attr_prox_cal,
  237. &dev_attr_prox_thresh,
  238. &dev_attr_barcode_emul_en,
  239. NULL,
  240. };
  241. void initialize_prox_factorytest(struct ssp_data *data)
  242. {
  243. struct device *prox_device = NULL;
  244. sensors_register(prox_device, data, prox_attrs, "proximity_sensor");
  245. }