cm36686.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899
  1. /*
  2. * Author: yucong xiong <yucong.xion@mediatek.com>
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. */
  14. #include <linux/interrupt.h>
  15. #include <linux/i2c.h>
  16. #include <linux/slab.h>
  17. #include <linux/irq.h>
  18. #include <linux/gpio.h>
  19. #include <linux/miscdevice.h>
  20. #include <asm/uaccess.h>
  21. #include <linux/delay.h>
  22. #include <linux/input.h>
  23. #include <linux/workqueue.h>
  24. #include <linux/kobject.h>
  25. #include <linux/platform_device.h>
  26. #include <asm/atomic.h>
  27. #include <asm/io.h>
  28. #include "cust_alsps.h"
  29. #include "cm36686.h"
  30. #include <linux/sched.h>
  31. #include <alsps.h>
  32. #include <linux/of.h>
  33. #include <linux/of_address.h>
  34. #include <linux/of_irq.h>
  35. /******************************************************************************
  36. * configuration
  37. *******************************************************************************/
  38. /*----------------------------------------------------------------------------*/
  39. #define CM36686_DEV_NAME "cm36686"
  40. /*----------------------------------------------------------------------------*/
  41. #define APS_TAG "[ALS/PS] "
  42. #define APS_FUN(f) pr_err(APS_TAG"%s\n", __func__)
  43. #define APS_ERR(fmt, args...) pr_err(APS_TAG"%s %d : "fmt, __func__, __LINE__, ##args)
  44. #define APS_LOG(fmt, args...) pr_err(APS_TAG fmt, ##args)
  45. #define APS_DBG(fmt, args...) pr_err(APS_TAG fmt, ##args)
  46. #define I2C_FLAG_WRITE 0
  47. #define I2C_FLAG_READ 1
  48. /******************************************************************************
  49. * extern functions
  50. *******************************************************************************/
  51. static int cm36686_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  52. static int cm36686_i2c_remove(struct i2c_client *client);
  53. static int cm36686_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
  54. static int cm36686_i2c_suspend(struct i2c_client *client, pm_message_t msg);
  55. static int cm36686_i2c_resume(struct i2c_client *client);
  56. /*----------------------------------------------------------------------------*/
  57. static const struct i2c_device_id cm36686_i2c_id[] = { {CM36686_DEV_NAME, 0}, {} };
  58. static unsigned long long int_top_time;
  59. /* Maintain alsps cust info here */
  60. struct alsps_hw alsps_cust;
  61. static struct alsps_hw *hw = &alsps_cust;
  62. struct platform_device *alspsPltFmDev;
  63. /* For alsp driver get cust info */
  64. struct alsps_hw *get_cust_alsps(void)
  65. {
  66. return &alsps_cust;
  67. }
  68. /*----------------------------------------------------------------------------*/
  69. struct cm36686_priv {
  70. struct alsps_hw *hw;
  71. struct i2c_client *client;
  72. struct work_struct eint_work;
  73. /*misc */
  74. u16 als_modulus;
  75. atomic_t i2c_retry;
  76. atomic_t als_suspend;
  77. atomic_t als_debounce; /*debounce time after enabling als */
  78. atomic_t als_deb_on; /*indicates if the debounce is on */
  79. #ifdef CONFIG_64BIT
  80. atomic64_t als_deb_end; /*the jiffies representing the end of debounce */
  81. #else
  82. atomic_t als_deb_end; /*the jiffies representing the end of debounce */
  83. #endif
  84. atomic_t ps_mask; /*mask ps: always return far away */
  85. atomic_t ps_debounce; /*debounce time after enabling ps */
  86. atomic_t ps_deb_on; /*indicates if the debounce is on */
  87. #ifdef CONFIG_64BIT
  88. atomic64_t ps_deb_end; /*the jiffies representing the end of debounce */
  89. #else
  90. atomic_t ps_deb_end; /*the jiffies representing the end of debounce */
  91. #endif
  92. atomic_t ps_suspend;
  93. atomic_t trace;
  94. atomic_t init_done;
  95. struct device_node *irq_node;
  96. int irq;
  97. /*data */
  98. u16 als;
  99. u16 ps;
  100. /* u8 _align; */
  101. u16 als_level_num;
  102. u16 als_value_num;
  103. u32 als_level[C_CUST_ALS_LEVEL - 1];
  104. u32 als_value[C_CUST_ALS_LEVEL];
  105. int ps_cali;
  106. atomic_t als_cmd_val; /*the cmd value can't be read, stored in ram */
  107. atomic_t ps_cmd_val; /*the cmd value can't be read, stored in ram */
  108. atomic_t ps_thd_val_high; /*the cmd value can't be read, stored in ram */
  109. atomic_t ps_thd_val_low; /*the cmd value can't be read, stored in ram */
  110. atomic_t als_thd_val_high; /*the cmd value can't be read, stored in ram */
  111. atomic_t als_thd_val_low; /*the cmd value can't be read, stored in ram */
  112. atomic_t ps_thd_val;
  113. ulong enable; /*enable mask */
  114. ulong pending_intr; /*pending interrupt */
  115. };
  116. /*----------------------------------------------------------------------------*/
  117. #ifdef CONFIG_OF
  118. static const struct of_device_id alsps_of_match[] = {
  119. {.compatible = "mediatek,alsps"},
  120. {},
  121. };
  122. #endif
  123. static struct i2c_driver cm36686_i2c_driver = {
  124. .probe = cm36686_i2c_probe,
  125. .remove = cm36686_i2c_remove,
  126. .detect = cm36686_i2c_detect,
  127. .suspend = cm36686_i2c_suspend,
  128. .resume = cm36686_i2c_resume,
  129. .id_table = cm36686_i2c_id,
  130. .driver = {
  131. .name = CM36686_DEV_NAME,
  132. #ifdef CONFIG_OF
  133. .of_match_table = alsps_of_match,
  134. #endif
  135. },
  136. };
  137. /*----------------------------------------------------------------------------*/
  138. struct PS_CALI_DATA_STRUCT {
  139. int close;
  140. int far_away;
  141. int valid;
  142. };
  143. /*----------------------------------------------------------------------------*/
  144. /*----------------------------------------------------------------------------*/
  145. static struct i2c_client *cm36686_i2c_client;
  146. static struct cm36686_priv *cm36686_obj;
  147. static int intr_flag = 1; /* hw default away after enable. */
  148. static int cm36686_local_init(void);
  149. static int cm36686_remove(void);
  150. static int cm36686_init_flag = -1; /* 0<==>OK -1 <==> fail */
  151. static struct alsps_init_info cm36686_init_info = {
  152. .name = "cm36686",
  153. .init = cm36686_local_init,
  154. .uninit = cm36686_remove,
  155. };
  156. /*----------------------------------------------------------------------------*/
  157. static DEFINE_MUTEX(cm36686_mutex);
  158. /*----------------------------------------------------------------------------*/
  159. typedef enum {
  160. CMC_BIT_ALS = 1,
  161. CMC_BIT_PS = 2,
  162. } CMC_BIT;
  163. /*-----------------------------CMC for debugging-------------------------------*/
  164. typedef enum {
  165. CMC_TRC_ALS_DATA = 0x0001,
  166. CMC_TRC_PS_DATA = 0x0002,
  167. CMC_TRC_EINT = 0x0004,
  168. CMC_TRC_IOCTL = 0x0008,
  169. CMC_TRC_I2C = 0x0010,
  170. CMC_TRC_CVT_ALS = 0x0020,
  171. CMC_TRC_CVT_PS = 0x0040,
  172. CMC_TRC_CVT_AAL = 0x0080,
  173. CMC_TRC_DEBUG = 0x8000,
  174. } CMC_TRC;
  175. /*-----------------------------------------------------------------------------*/
  176. int CM36686_i2c_master_operate(struct i2c_client *client, const char *buf, int count, int i2c_flag)
  177. {
  178. int res = 0;
  179. mutex_lock(&cm36686_mutex);
  180. switch (i2c_flag) {
  181. case I2C_FLAG_WRITE:
  182. client->addr &= I2C_MASK_FLAG;
  183. res = i2c_master_send(client, buf, count);
  184. client->addr &= I2C_MASK_FLAG;
  185. break;
  186. case I2C_FLAG_READ:
  187. client->addr &= I2C_MASK_FLAG;
  188. client->addr |= I2C_WR_FLAG;
  189. client->addr |= I2C_RS_FLAG;
  190. res = i2c_master_send(client, buf, count);
  191. client->addr &= I2C_MASK_FLAG;
  192. break;
  193. default:
  194. APS_LOG("CM36686_i2c_master_operate i2c_flag command not support!\n");
  195. break;
  196. }
  197. if (res < 0)
  198. goto EXIT_ERR;
  199. mutex_unlock(&cm36686_mutex);
  200. return res;
  201. EXIT_ERR:
  202. mutex_unlock(&cm36686_mutex);
  203. APS_ERR("CM36686_i2c_master_operate fail\n");
  204. return res;
  205. }
  206. /*----------------------------------------------------------------------------*/
  207. static void cm36686_power(struct alsps_hw *hw, unsigned int on)
  208. {
  209. }
  210. /********************************************************************/
  211. int cm36686_enable_ps(struct i2c_client *client, int enable)
  212. {
  213. struct cm36686_priv *obj = i2c_get_clientdata(client);
  214. int res;
  215. u8 databuf[3];
  216. if (enable == 1) {
  217. APS_LOG("cm36686_enable_ps enable_ps\n");
  218. databuf[0] = CM36686_REG_PS_CONF1_2;
  219. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  220. if (res < 0) {
  221. APS_ERR("i2c_master_send function err\n");
  222. goto ENABLE_PS_EXIT_ERR;
  223. }
  224. APS_LOG("CM36686_REG_PS_CONF1_2 value value_low = %x, value_high = %x\n",
  225. databuf[0], databuf[1]);
  226. databuf[2] = databuf[1];
  227. databuf[1] = databuf[0] & 0xFE;
  228. databuf[0] = CM36686_REG_PS_CONF1_2;
  229. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  230. if (res < 0) {
  231. APS_ERR("i2c_master_send function err\n");
  232. goto ENABLE_PS_EXIT_ERR;
  233. }
  234. atomic_set(&obj->ps_deb_on, 1);
  235. #ifdef CONFIG_64BIT
  236. atomic64_set(&obj->ps_deb_end,
  237. jiffies + atomic_read(&obj->ps_debounce) / (1000 / HZ));
  238. #else
  239. atomic_set(&obj->ps_deb_end,
  240. jiffies + atomic_read(&obj->ps_debounce) / (1000 / HZ));
  241. #endif
  242. intr_flag = 1; /* reset hw status to away after enable. */
  243. } else {
  244. APS_LOG("cm36686_enable_ps disable_ps\n");
  245. databuf[0] = CM36686_REG_PS_CONF1_2;
  246. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  247. if (res < 0) {
  248. APS_ERR("i2c_master_send function err\n");
  249. goto ENABLE_PS_EXIT_ERR;
  250. }
  251. APS_LOG("CM36686_REG_PS_CONF1_2 value value_low = %x, value_high = %x\n",
  252. databuf[0], databuf[1]);
  253. databuf[2] = databuf[1];
  254. databuf[1] = databuf[0] | 0x01;
  255. databuf[0] = CM36686_REG_PS_CONF1_2;
  256. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  257. if (res < 0) {
  258. APS_ERR("i2c_master_send function err\n");
  259. goto ENABLE_PS_EXIT_ERR;
  260. }
  261. atomic_set(&obj->ps_deb_on, 0);
  262. }
  263. return 0;
  264. ENABLE_PS_EXIT_ERR:
  265. return res;
  266. }
  267. /********************************************************************/
  268. int cm36686_enable_als(struct i2c_client *client, int enable)
  269. {
  270. struct cm36686_priv *obj = i2c_get_clientdata(client);
  271. int res;
  272. u8 databuf[3];
  273. if (enable == 1) {
  274. APS_LOG("cm36686_enable_als enable_als\n");
  275. databuf[0] = CM36686_REG_ALS_CONF;
  276. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  277. if (res < 0) {
  278. APS_ERR("i2c_master_send function err\n");
  279. goto ENABLE_ALS_EXIT_ERR;
  280. }
  281. APS_LOG("CM36686_REG_ALS_CONF value value_low = %x, value_high = %x\n", databuf[0],
  282. databuf[1]);
  283. databuf[2] = databuf[1];
  284. databuf[1] = databuf[0] & 0xFE;
  285. databuf[0] = CM36686_REG_ALS_CONF;
  286. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  287. if (res < 0) {
  288. APS_ERR("i2c_master_send function err\n");
  289. goto ENABLE_ALS_EXIT_ERR;
  290. }
  291. atomic_set(&obj->als_deb_on, 1);
  292. #ifdef CONFIG_64BIT
  293. atomic64_set(&obj->als_deb_end,
  294. jiffies + atomic_read(&obj->als_debounce) / (1000 / HZ));
  295. #else
  296. atomic_set(&obj->als_deb_end,
  297. jiffies + atomic_read(&obj->als_debounce) / (1000 / HZ));
  298. #endif
  299. } else {
  300. APS_LOG("cm36686_enable_als disable_als\n");
  301. databuf[0] = CM36686_REG_ALS_CONF;
  302. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  303. if (res < 0) {
  304. APS_ERR("i2c_master_send function err\n");
  305. goto ENABLE_ALS_EXIT_ERR;
  306. }
  307. APS_LOG("CM36686_REG_ALS_CONF value value_low = %x, value_high = %x\n", databuf[0],
  308. databuf[1]);
  309. databuf[2] = databuf[1];
  310. databuf[1] = databuf[0] | 0x01;
  311. databuf[0] = CM36686_REG_ALS_CONF;
  312. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  313. if (res < 0) {
  314. APS_ERR("i2c_master_send function err\n");
  315. goto ENABLE_ALS_EXIT_ERR;
  316. }
  317. atomic_set(&obj->als_deb_on, 0);
  318. }
  319. return 0;
  320. ENABLE_ALS_EXIT_ERR:
  321. return res;
  322. }
  323. /********************************************************************/
  324. long cm36686_read_ps(struct i2c_client *client, u16 *data)
  325. {
  326. long res;
  327. u8 databuf[2];
  328. struct cm36686_priv *obj = i2c_get_clientdata(client);
  329. databuf[0] = CM36686_REG_PS_DATA;
  330. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  331. if (res < 0) {
  332. APS_ERR("i2c_master_send function err\n");
  333. goto READ_PS_EXIT_ERR;
  334. }
  335. if (atomic_read(&obj->trace) & CMC_TRC_DEBUG) {
  336. APS_LOG("CM36686_REG_PS_DATA value value_low = %x, value_high = %x\n", databuf[0],
  337. databuf[1]);
  338. }
  339. *data = ((databuf[1] << 8) | databuf[0]);
  340. if (*data < obj->ps_cali)
  341. *data = 0;
  342. else
  343. *data = *data - obj->ps_cali;
  344. return 0;
  345. READ_PS_EXIT_ERR:
  346. return res;
  347. }
  348. /********************************************************************/
  349. long cm36686_read_als(struct i2c_client *client, u16 *data)
  350. {
  351. long res;
  352. u8 databuf[2];
  353. struct cm36686_priv *obj = i2c_get_clientdata(client);
  354. databuf[0] = CM36686_REG_ALS_DATA;
  355. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  356. if (res < 0) {
  357. APS_ERR("i2c_master_send function err\n");
  358. goto READ_ALS_EXIT_ERR;
  359. }
  360. if (atomic_read(&obj->trace) & CMC_TRC_DEBUG)
  361. APS_LOG("CM36686_REG_ALS_DATA value: %d\n", ((databuf[1] << 8) | databuf[0]));
  362. *data = ((databuf[1] << 8) | databuf[0]);
  363. return 0;
  364. READ_ALS_EXIT_ERR:
  365. return res;
  366. }
  367. /********************************************************************/
  368. static int cm36686_get_ps_value(struct cm36686_priv *obj, u16 ps)
  369. {
  370. int val, mask = atomic_read(&obj->ps_mask);
  371. int invalid = 0;
  372. val = intr_flag; /* value between high/low threshold should sync. with hw status. */
  373. if (ps > atomic_read(&obj->ps_thd_val_high))
  374. val = 0; /*close */
  375. else if (ps < atomic_read(&obj->ps_thd_val_low))
  376. val = 1; /*far away */
  377. if (atomic_read(&obj->ps_suspend)) {
  378. invalid = 1;
  379. } else if (1 == atomic_read(&obj->ps_deb_on)) {
  380. #ifdef CONFIG_64BIT
  381. unsigned long endt = atomic64_read(&obj->ps_deb_end);
  382. #else
  383. unsigned long endt = atomic_read(&obj->ps_deb_end);
  384. #endif
  385. if (time_after(jiffies, endt))
  386. atomic_set(&obj->ps_deb_on, 0);
  387. if (1 == atomic_read(&obj->ps_deb_on))
  388. invalid = 1;
  389. }
  390. if (!invalid) {
  391. if (unlikely(atomic_read(&obj->trace) & CMC_TRC_CVT_PS)) {
  392. if (mask)
  393. APS_DBG("PS: %05d => %05d [M]\n", ps, val);
  394. else
  395. APS_DBG("PS: %05d => %05d\n", ps, val);
  396. }
  397. if (0 == test_bit(CMC_BIT_PS, &obj->enable)) {
  398. /* if ps is disable do not report value */
  399. APS_DBG("PS: not enable and do not report this value\n");
  400. return -1;
  401. } else {
  402. return val;
  403. }
  404. } else {
  405. if (unlikely(atomic_read(&obj->trace) & CMC_TRC_CVT_PS))
  406. APS_DBG("PS: %05d => %05d (-1)\n", ps, val);
  407. return -1;
  408. }
  409. }
  410. /********************************************************************/
  411. static int cm36686_get_als_value(struct cm36686_priv *obj, u16 als)
  412. {
  413. int idx = 0;
  414. int invalid = 0;
  415. int level_high = 0;
  416. int level_low = 0;
  417. int level_diff = 0;
  418. int value_high = 0;
  419. int value_low = 0;
  420. int value_diff = 0;
  421. int value = 0;
  422. if ((0 == obj->als_level_num) || (0 == obj->als_value_num)) {
  423. APS_ERR("invalid als_level_num = %d, als_value_num = %d\n", obj->als_level_num,
  424. obj->als_value_num);
  425. return -1;
  426. }
  427. if (1 == atomic_read(&obj->als_deb_on)) {
  428. #ifdef CONFIG_64BIT
  429. unsigned long endt = (unsigned long)atomic64_read(&obj->als_deb_end);
  430. #else
  431. unsigned long endt = (unsigned long)atomic_read(&obj->als_deb_end);
  432. #endif
  433. if (time_after(jiffies, endt))
  434. atomic_set(&obj->als_deb_on, 0);
  435. if (1 == atomic_read(&obj->als_deb_on))
  436. invalid = 1;
  437. }
  438. for (idx = 0; idx < obj->als_level_num; idx++) {
  439. if (als < obj->hw->als_level[idx])
  440. break;
  441. }
  442. if (idx >= obj->als_level_num || idx >= obj->als_value_num) {
  443. if (idx < obj->als_value_num)
  444. value = obj->hw->als_value[idx - 1];
  445. else
  446. value = obj->hw->als_value[obj->als_value_num - 1];
  447. } else {
  448. level_high = obj->hw->als_level[idx];
  449. level_low = (idx > 0) ? obj->hw->als_level[idx - 1] : 0;
  450. level_diff = level_high - level_low;
  451. value_high = obj->hw->als_value[idx];
  452. value_low = (idx > 0) ? obj->hw->als_value[idx - 1] : 0;
  453. value_diff = value_high - value_low;
  454. if ((level_low >= level_high) || (value_low >= value_high))
  455. value = value_low;
  456. else
  457. value =
  458. (level_diff * value_low + (als - level_low) * value_diff +
  459. ((level_diff + 1) >> 1)) / level_diff;
  460. }
  461. if (!invalid) {
  462. if (atomic_read(&obj->trace) & CMC_TRC_CVT_AAL)
  463. APS_DBG("ALS: %d [%d, %d] => %d [%d, %d]\n", als, level_low, level_high,
  464. value, value_low, value_high);
  465. return value;
  466. } else {
  467. if (atomic_read(&obj->trace) & CMC_TRC_CVT_ALS)
  468. APS_DBG("ALS: %05d => %05d (-1)\n", als, value);
  469. return -1;
  470. }
  471. }
  472. /*-------------------------------attribute file for debugging----------------------------------*/
  473. /******************************************************************************
  474. * Sysfs attributes
  475. *******************************************************************************/
  476. static ssize_t cm36686_show_config(struct device_driver *ddri, char *buf)
  477. {
  478. ssize_t res;
  479. if (!cm36686_obj) {
  480. APS_ERR("cm36686_obj is null!!\n");
  481. return 0;
  482. }
  483. res = snprintf(buf, PAGE_SIZE, "(%d %d %d %d %d)\n",
  484. atomic_read(&cm36686_obj->i2c_retry),
  485. atomic_read(&cm36686_obj->als_debounce), atomic_read(&cm36686_obj->ps_mask),
  486. atomic_read(&cm36686_obj->ps_thd_val),
  487. atomic_read(&cm36686_obj->ps_debounce));
  488. return res;
  489. }
  490. /*----------------------------------------------------------------------------*/
  491. static ssize_t cm36686_store_config(struct device_driver *ddri, const char *buf, size_t count)
  492. {
  493. int retry, als_deb, ps_deb, mask, thres;
  494. if (!cm36686_obj) {
  495. APS_ERR("cm36686_obj is null!!\n");
  496. return 0;
  497. }
  498. if (5 == sscanf(buf, "%d %d %d %d %d", &retry, &als_deb, &mask, &thres, &ps_deb)) {
  499. atomic_set(&cm36686_obj->i2c_retry, retry);
  500. atomic_set(&cm36686_obj->als_debounce, als_deb);
  501. atomic_set(&cm36686_obj->ps_mask, mask);
  502. atomic_set(&cm36686_obj->ps_thd_val, thres);
  503. atomic_set(&cm36686_obj->ps_debounce, ps_deb);
  504. } else {
  505. APS_ERR("invalid content: '%s', length = %zu\n", buf, count);
  506. }
  507. return count;
  508. }
  509. /*----------------------------------------------------------------------------*/
  510. static ssize_t cm36686_show_trace(struct device_driver *ddri, char *buf)
  511. {
  512. ssize_t res;
  513. if (!cm36686_obj) {
  514. APS_ERR("cm36686_obj is null!!\n");
  515. return 0;
  516. }
  517. res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&cm36686_obj->trace));
  518. return res;
  519. }
  520. /*----------------------------------------------------------------------------*/
  521. static ssize_t cm36686_store_trace(struct device_driver *ddri, const char *buf, size_t count)
  522. {
  523. int trace;
  524. if (!cm36686_obj) {
  525. APS_ERR("cm36686_obj is null!!\n");
  526. return 0;
  527. }
  528. if (1 == sscanf(buf, "0x%x", &trace))
  529. atomic_set(&cm36686_obj->trace, trace);
  530. else
  531. APS_ERR("invalid content: '%s', length = %zu\n", buf, count);
  532. return count;
  533. }
  534. /*----------------------------------------------------------------------------*/
  535. static ssize_t cm36686_show_als(struct device_driver *ddri, char *buf)
  536. {
  537. int res;
  538. if (!cm36686_obj) {
  539. APS_ERR("cm36686_obj is null!!\n");
  540. return 0;
  541. }
  542. res = cm36686_read_als(cm36686_obj->client, &cm36686_obj->als);
  543. if (res)
  544. return snprintf(buf, PAGE_SIZE, "ERROR: %d\n", res);
  545. else
  546. return snprintf(buf, PAGE_SIZE, "0x%04X\n", cm36686_obj->als);
  547. }
  548. /*----------------------------------------------------------------------------*/
  549. static ssize_t cm36686_show_ps(struct device_driver *ddri, char *buf)
  550. {
  551. ssize_t res;
  552. if (!cm36686_obj) {
  553. APS_ERR("cm3623_obj is null!!\n");
  554. return 0;
  555. }
  556. res = cm36686_read_ps(cm36686_obj->client, &cm36686_obj->ps);
  557. if (res)
  558. return snprintf(buf, PAGE_SIZE, "ERROR: %d\n", (int)res);
  559. else
  560. return snprintf(buf, PAGE_SIZE, "0x%04X\n", cm36686_obj->ps);
  561. }
  562. /*----------------------------------------------------------------------------*/
  563. static ssize_t cm36686_show_reg(struct device_driver *ddri, char *buf)
  564. {
  565. u8 _bIndex = 0;
  566. u8 databuf[2] = { 0 };
  567. ssize_t _tLength = 0;
  568. if (!cm36686_obj) {
  569. APS_ERR("cm3623_obj is null!!\n");
  570. return 0;
  571. }
  572. for (_bIndex = 0; _bIndex < 0x0D; _bIndex++) {
  573. databuf[0] = _bIndex;
  574. CM36686_i2c_master_operate(cm36686_obj->client, databuf, 0x201, I2C_FLAG_READ);
  575. _tLength +=
  576. snprintf((buf + _tLength), (PAGE_SIZE - _tLength), "Reg[0x%02X]: 0x%02X\n",
  577. _bIndex, databuf[0]);
  578. }
  579. return _tLength;
  580. }
  581. /*----------------------------------------------------------------------------*/
  582. static ssize_t cm36686_show_send(struct device_driver *ddri, char *buf)
  583. {
  584. return 0;
  585. }
  586. /*----------------------------------------------------------------------------*/
  587. static ssize_t cm36686_store_send(struct device_driver *ddri, const char *buf, size_t count)
  588. {
  589. int addr, cmd;
  590. u8 dat;
  591. if (!cm36686_obj) {
  592. APS_ERR("cm36686_obj is null!!\n");
  593. return 0;
  594. } else if (2 != sscanf(buf, "%x %x", &addr, &cmd)) {
  595. APS_ERR("invalid format: '%s'\n", buf);
  596. return 0;
  597. }
  598. dat = (u8) cmd;
  599. return count;
  600. }
  601. /*----------------------------------------------------------------------------*/
  602. static ssize_t cm36686_show_recv(struct device_driver *ddri, char *buf)
  603. {
  604. return 0;
  605. }
  606. /*----------------------------------------------------------------------------*/
  607. static ssize_t cm36686_store_recv(struct device_driver *ddri, const char *buf, size_t count)
  608. {
  609. int addr;
  610. int ret;
  611. if (!cm36686_obj) {
  612. APS_ERR("cm36686_obj is null!!\n");
  613. return 0;
  614. }
  615. ret = kstrtoint(buf, 16, &addr);
  616. if (ret < 0) {
  617. APS_ERR("invalid format: '%s'\n", buf);
  618. return 0;
  619. }
  620. return count;
  621. }
  622. /*----------------------------------------------------------------------------*/
  623. static ssize_t cm36686_show_status(struct device_driver *ddri, char *buf)
  624. {
  625. ssize_t len = 0;
  626. if (!cm36686_obj) {
  627. APS_ERR("cm36686_obj is null!!\n");
  628. return 0;
  629. }
  630. if (cm36686_obj->hw) {
  631. len += snprintf(buf + len, PAGE_SIZE - len, "CUST: %d, (%d %d)\n",
  632. cm36686_obj->hw->i2c_num, cm36686_obj->hw->power_id,
  633. cm36686_obj->hw->power_vol);
  634. } else {
  635. len += snprintf(buf + len, PAGE_SIZE - len, "CUST: NULL\n");
  636. }
  637. len += snprintf(buf + len, PAGE_SIZE - len, "REGS: %02X %02X %02X %02lX %02lX\n",
  638. atomic_read(&cm36686_obj->als_cmd_val),
  639. atomic_read(&cm36686_obj->ps_cmd_val),
  640. atomic_read(&cm36686_obj->ps_thd_val), cm36686_obj->enable,
  641. cm36686_obj->pending_intr);
  642. len +=
  643. snprintf(buf + len, PAGE_SIZE - len, "MISC: %d %d\n",
  644. atomic_read(&cm36686_obj->als_suspend), atomic_read(&cm36686_obj->ps_suspend));
  645. return len;
  646. }
  647. /*----------------------------------------------------------------------------*/
  648. /*----------------------------------------------------------------------------*/
  649. #define IS_SPACE(CH) (((CH) == ' ') || ((CH) == '\n'))
  650. /*----------------------------------------------------------------------------*/
  651. static int read_int_from_buf(struct cm36686_priv *obj, const char *buf, size_t count, u32 data[],
  652. int len)
  653. {
  654. int idx = 0;
  655. int ret;
  656. char *cur = (char *)buf, *end = (char *)(buf + count);
  657. while (idx < len) {
  658. while ((cur < end) && IS_SPACE(*cur))
  659. cur++;
  660. ret = kstrtoint(cur, 10, &data[idx]);
  661. if (ret < 0)
  662. break;
  663. idx++;
  664. while ((cur < end) && !IS_SPACE(*cur))
  665. cur++;
  666. }
  667. return idx;
  668. }
  669. /*----------------------------------------------------------------------------*/
  670. static ssize_t cm36686_show_alslv(struct device_driver *ddri, char *buf)
  671. {
  672. ssize_t len = 0;
  673. int idx;
  674. if (!cm36686_obj) {
  675. APS_ERR("cm36686_obj is null!!\n");
  676. return 0;
  677. }
  678. for (idx = 0; idx < cm36686_obj->als_level_num; idx++)
  679. len += snprintf(buf + len, PAGE_SIZE - len, "%d ", cm36686_obj->hw->als_level[idx]);
  680. len += snprintf(buf + len, PAGE_SIZE - len, "\n");
  681. return len;
  682. }
  683. /*----------------------------------------------------------------------------*/
  684. static ssize_t cm36686_store_alslv(struct device_driver *ddri, const char *buf, size_t count)
  685. {
  686. if (!cm36686_obj) {
  687. APS_ERR("cm36686_obj is null!!\n");
  688. return 0;
  689. } else if (!strcmp(buf, "def")) {
  690. memcpy(cm36686_obj->als_level, cm36686_obj->hw->als_level,
  691. sizeof(cm36686_obj->als_level));
  692. } else if (cm36686_obj->als_level_num !=
  693. read_int_from_buf(cm36686_obj, buf, count, cm36686_obj->hw->als_level,
  694. cm36686_obj->als_level_num)) {
  695. APS_ERR("invalid format: '%s'\n", buf);
  696. }
  697. return count;
  698. }
  699. /*----------------------------------------------------------------------------*/
  700. static ssize_t cm36686_show_alsval(struct device_driver *ddri, char *buf)
  701. {
  702. ssize_t len = 0;
  703. int idx;
  704. if (!cm36686_obj) {
  705. APS_ERR("cm36686_obj is null!!\n");
  706. return 0;
  707. }
  708. for (idx = 0; idx < cm36686_obj->als_value_num; idx++)
  709. len += snprintf(buf + len, PAGE_SIZE - len, "%d ", cm36686_obj->hw->als_value[idx]);
  710. len += snprintf(buf + len, PAGE_SIZE - len, "\n");
  711. return len;
  712. }
  713. /*----------------------------------------------------------------------------*/
  714. static ssize_t cm36686_store_alsval(struct device_driver *ddri, const char *buf, size_t count)
  715. {
  716. if (!cm36686_obj) {
  717. APS_ERR("cm36686_obj is null!!\n");
  718. return 0;
  719. } else if (!strcmp(buf, "def")) {
  720. memcpy(cm36686_obj->als_value, cm36686_obj->hw->als_value,
  721. sizeof(cm36686_obj->als_value));
  722. } else if (cm36686_obj->als_value_num !=
  723. read_int_from_buf(cm36686_obj, buf, count, cm36686_obj->hw->als_value,
  724. cm36686_obj->als_value_num)) {
  725. APS_ERR("invalid format: '%s'\n", buf);
  726. }
  727. return count;
  728. }
  729. /*---------------------------------------------------------------------------------------*/
  730. static DRIVER_ATTR(als, S_IWUSR | S_IRUGO, cm36686_show_als, NULL);
  731. static DRIVER_ATTR(ps, S_IWUSR | S_IRUGO, cm36686_show_ps, NULL);
  732. static DRIVER_ATTR(config, S_IWUSR | S_IRUGO, cm36686_show_config, cm36686_store_config);
  733. static DRIVER_ATTR(alslv, S_IWUSR | S_IRUGO, cm36686_show_alslv, cm36686_store_alslv);
  734. static DRIVER_ATTR(alsval, S_IWUSR | S_IRUGO, cm36686_show_alsval, cm36686_store_alsval);
  735. static DRIVER_ATTR(trace, S_IWUSR | S_IRUGO, cm36686_show_trace, cm36686_store_trace);
  736. static DRIVER_ATTR(status, S_IWUSR | S_IRUGO, cm36686_show_status, NULL);
  737. static DRIVER_ATTR(send, S_IWUSR | S_IRUGO, cm36686_show_send, cm36686_store_send);
  738. static DRIVER_ATTR(recv, S_IWUSR | S_IRUGO, cm36686_show_recv, cm36686_store_recv);
  739. static DRIVER_ATTR(reg, S_IWUSR | S_IRUGO, cm36686_show_reg, NULL);
  740. /*----------------------------------------------------------------------------*/
  741. static struct driver_attribute *cm36686_attr_list[] = {
  742. &driver_attr_als,
  743. &driver_attr_ps,
  744. &driver_attr_trace, /*trace log */
  745. &driver_attr_config,
  746. &driver_attr_alslv,
  747. &driver_attr_alsval,
  748. &driver_attr_status,
  749. &driver_attr_send,
  750. &driver_attr_recv,
  751. &driver_attr_reg,
  752. };
  753. /*----------------------------------------------------------------------------*/
  754. static int cm36686_create_attr(struct device_driver *driver)
  755. {
  756. int idx, err = 0;
  757. int num = (int)(sizeof(cm36686_attr_list) / sizeof(cm36686_attr_list[0]));
  758. if (driver == NULL)
  759. return -EINVAL;
  760. for (idx = 0; idx < num; idx++) {
  761. err = driver_create_file(driver, cm36686_attr_list[idx]);
  762. if (err) {
  763. APS_ERR("driver_create_file (%s) = %d\n", cm36686_attr_list[idx]->attr.name,
  764. err);
  765. break;
  766. }
  767. }
  768. return err;
  769. }
  770. /*----------------------------------------------------------------------------*/
  771. static int cm36686_delete_attr(struct device_driver *driver)
  772. {
  773. int idx, err = 0;
  774. int num = (int)(sizeof(cm36686_attr_list) / sizeof(cm36686_attr_list[0]));
  775. if (!driver)
  776. return -EINVAL;
  777. for (idx = 0; idx < num; idx++)
  778. driver_remove_file(driver, cm36686_attr_list[idx]);
  779. return err;
  780. }
  781. /*----------------------------------------------------------------------------*/
  782. /*----------------------------------interrupt functions--------------------------------*/
  783. static int cm36686_check_intr(struct i2c_client *client)
  784. {
  785. int res;
  786. u8 databuf[2];
  787. databuf[0] = CM36686_REG_PS_DATA;
  788. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  789. if (res < 0) {
  790. APS_ERR("i2c_master_send function err res = %d\n", res);
  791. goto EXIT_ERR;
  792. }
  793. APS_LOG("CM36686_REG_PS_DATA value value_low = %x, value_high = %x\n", databuf[0],
  794. databuf[1]);
  795. databuf[0] = CM36686_REG_INT_FLAG;
  796. res = CM36686_i2c_master_operate(client, databuf, 0x201, I2C_FLAG_READ);
  797. if (res < 0) {
  798. APS_ERR("i2c_master_send function err res = %d\n", res);
  799. goto EXIT_ERR;
  800. }
  801. APS_LOG("CM36686_REG_INT_FLAG value value_low = %x, value_high = %x\n", databuf[0],
  802. databuf[1]);
  803. if (databuf[1] & 0x02) {
  804. intr_flag = 0; /* for close */
  805. } else if (databuf[1] & 0x01) {
  806. intr_flag = 1; /* for away */
  807. } else {
  808. res = -1;
  809. APS_ERR("cm36686_check_intr fail databuf[1]&0x01: %d\n", res);
  810. goto EXIT_ERR;
  811. }
  812. return 0;
  813. EXIT_ERR:
  814. APS_ERR("cm36686_check_intr dev: %d\n", res);
  815. return res;
  816. }
  817. /*----------------------------------------------------------------------------*/
  818. static void cm36686_eint_work(struct work_struct *work)
  819. {
  820. struct cm36686_priv *obj =
  821. (struct cm36686_priv *)container_of(work, struct cm36686_priv, eint_work);
  822. int res = 0;
  823. APS_LOG("cm36686 int top half time = %lld\n", int_top_time);
  824. res = cm36686_check_intr(obj->client);
  825. if (res != 0) {
  826. goto EXIT_INTR_ERR;
  827. } else {
  828. APS_LOG("cm36686 interrupt value = %d\n", intr_flag);
  829. res = ps_report_interrupt_data(intr_flag);
  830. }
  831. enable_irq(obj->irq);
  832. return;
  833. EXIT_INTR_ERR:
  834. enable_irq(obj->irq);
  835. APS_ERR("cm36686_eint_work err: %d\n", res);
  836. }
  837. /*----------------------------------------------------------------------------*/
  838. static void cm36686_eint_func(void)
  839. {
  840. struct cm36686_priv *obj = cm36686_obj;
  841. if (!obj)
  842. return;
  843. int_top_time = sched_clock();
  844. schedule_work(&obj->eint_work);
  845. }
  846. #if defined(CONFIG_OF)
  847. static irqreturn_t cm36686_eint_handler(int irq, void *desc)
  848. {
  849. cm36686_eint_func();
  850. disable_irq_nosync(cm36686_obj->irq);
  851. return IRQ_HANDLED;
  852. }
  853. #endif
  854. /*----------------------------------------------------------------------------*/
  855. int cm36686_setup_eint(struct i2c_client *client)
  856. {
  857. #if defined(CONFIG_OF)
  858. u32 ints[2] = { 0, 0 };
  859. #endif
  860. int ret;
  861. struct pinctrl *pinctrl;
  862. struct pinctrl_state *pins_default;
  863. struct pinctrl_state *pins_cfg;
  864. alspsPltFmDev = get_alsps_platformdev();
  865. pinctrl = devm_pinctrl_get(&alspsPltFmDev->dev);
  866. if (IS_ERR(pinctrl)) {
  867. ret = PTR_ERR(pinctrl);
  868. APS_ERR("Cannot find alsps pinctrl!\n");
  869. }
  870. pins_default = pinctrl_lookup_state(pinctrl, "pin_default");
  871. if (IS_ERR(pins_default)) {
  872. ret = PTR_ERR(pins_default);
  873. APS_ERR("Cannot find alsps pinctrl default!\n");
  874. }
  875. pins_cfg = pinctrl_lookup_state(pinctrl, "pin_cfg");
  876. if (IS_ERR(pins_cfg)) {
  877. ret = PTR_ERR(pins_cfg);
  878. APS_ERR("Cannot find alsps pinctrl pin_cfg!\n");
  879. }
  880. pinctrl_select_state(pinctrl, pins_cfg);
  881. if (cm36686_obj->irq_node) {
  882. of_property_read_u32_array(cm36686_obj->irq_node, "debounce", ints,
  883. ARRAY_SIZE(ints));
  884. gpio_request(ints[0], "p-sensor");
  885. gpio_set_debounce(ints[0], ints[1]);
  886. APS_LOG("ints[0] = %d, ints[1] = %d!!\n", ints[0], ints[1]);
  887. cm36686_obj->irq = irq_of_parse_and_map(cm36686_obj->irq_node, 0);
  888. APS_LOG("cm36686_obj->irq = %d\n", cm36686_obj->irq);
  889. if (!cm36686_obj->irq) {
  890. APS_ERR("irq_of_parse_and_map fail!!\n");
  891. return -EINVAL;
  892. }
  893. if (request_irq
  894. (cm36686_obj->irq, cm36686_eint_handler, IRQF_TRIGGER_NONE, "ALS-eint", NULL)) {
  895. APS_ERR("IRQ LINE NOT AVAILABLE!!\n");
  896. return -EINVAL;
  897. }
  898. enable_irq(cm36686_obj->irq);
  899. } else {
  900. APS_ERR("null irq node!!\n");
  901. return -EINVAL;
  902. }
  903. return 0;
  904. }
  905. /*-------------------------------MISC device related------------------------------------------*/
  906. /************************************************************/
  907. static int cm36686_open(struct inode *inode, struct file *file)
  908. {
  909. file->private_data = cm36686_i2c_client;
  910. if (!file->private_data) {
  911. APS_ERR("null pointer!!\n");
  912. return -EINVAL;
  913. }
  914. return nonseekable_open(inode, file);
  915. }
  916. /************************************************************/
  917. static int cm36686_release(struct inode *inode, struct file *file)
  918. {
  919. file->private_data = NULL;
  920. return 0;
  921. }
  922. /************************************************************/
  923. static int set_psensor_threshold(struct i2c_client *client)
  924. {
  925. struct cm36686_priv *obj = i2c_get_clientdata(client);
  926. int res = 0;
  927. u8 databuf[3];
  928. APS_ERR("set_psensor_threshold function high: 0x%x, low:0x%x\n",
  929. atomic_read(&obj->ps_thd_val_high), atomic_read(&obj->ps_thd_val_low));
  930. databuf[0] = CM36686_REG_PS_THDL;
  931. databuf[1] = atomic_read(&obj->ps_thd_val_low);
  932. databuf[2] = atomic_read(&obj->ps_thd_val_low) >> 8;
  933. res = CM36686_i2c_master_operate(client, databuf, 3, I2C_FLAG_WRITE);
  934. if (res <= 0) {
  935. APS_ERR("i2c_master_send function err\n");
  936. return -1;
  937. }
  938. databuf[0] = CM36686_REG_PS_THDH;
  939. databuf[1] = atomic_read(&obj->ps_thd_val_high);
  940. databuf[2] = atomic_read(&obj->ps_thd_val_high) >> 8;
  941. res = CM36686_i2c_master_operate(client, databuf, 3, I2C_FLAG_WRITE);
  942. if (res <= 0) {
  943. APS_ERR("i2c_master_send function err\n");
  944. return -1;
  945. }
  946. return 0;
  947. }
  948. static long cm36686_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  949. {
  950. struct i2c_client *client = (struct i2c_client *)file->private_data;
  951. struct cm36686_priv *obj = i2c_get_clientdata(client);
  952. long err = 0;
  953. void __user *ptr = (void __user *)arg;
  954. int dat;
  955. uint32_t enable;
  956. int ps_result;
  957. int ps_cali;
  958. int threshold[2];
  959. switch (cmd) {
  960. case ALSPS_SET_PS_MODE:
  961. if (copy_from_user(&enable, ptr, sizeof(enable))) {
  962. err = -EFAULT;
  963. goto err_out;
  964. }
  965. if (enable) {
  966. err = cm36686_enable_ps(obj->client, 1);
  967. if (err) {
  968. APS_ERR("enable ps fail: %ld\n", err);
  969. goto err_out;
  970. }
  971. set_bit(CMC_BIT_PS, &obj->enable);
  972. } else {
  973. err = cm36686_enable_ps(obj->client, 0);
  974. if (err) {
  975. APS_ERR("disable ps fail: %ld\n", err);
  976. goto err_out;
  977. }
  978. clear_bit(CMC_BIT_PS, &obj->enable);
  979. }
  980. break;
  981. case ALSPS_GET_PS_MODE:
  982. enable = test_bit(CMC_BIT_PS, &obj->enable) ? (1) : (0);
  983. if (copy_to_user(ptr, &enable, sizeof(enable))) {
  984. err = -EFAULT;
  985. goto err_out;
  986. }
  987. break;
  988. case ALSPS_GET_PS_DATA:
  989. err = cm36686_read_ps(obj->client, &obj->ps);
  990. if (err)
  991. goto err_out;
  992. dat = cm36686_get_ps_value(obj, obj->ps);
  993. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  994. err = -EFAULT;
  995. goto err_out;
  996. }
  997. break;
  998. case ALSPS_GET_PS_RAW_DATA:
  999. err = cm36686_read_ps(obj->client, &obj->ps);
  1000. if (err)
  1001. goto err_out;
  1002. dat = obj->ps;
  1003. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1004. err = -EFAULT;
  1005. goto err_out;
  1006. }
  1007. break;
  1008. case ALSPS_SET_ALS_MODE:
  1009. if (copy_from_user(&enable, ptr, sizeof(enable))) {
  1010. err = -EFAULT;
  1011. goto err_out;
  1012. }
  1013. if (enable) {
  1014. err = cm36686_enable_als(obj->client, 1);
  1015. if (err) {
  1016. APS_ERR("enable als fail: %ld\n", err);
  1017. goto err_out;
  1018. }
  1019. set_bit(CMC_BIT_ALS, &obj->enable);
  1020. } else {
  1021. err = cm36686_enable_als(obj->client, 0);
  1022. if (err) {
  1023. APS_ERR("disable als fail: %ld\n", err);
  1024. goto err_out;
  1025. }
  1026. clear_bit(CMC_BIT_ALS, &obj->enable);
  1027. }
  1028. break;
  1029. case ALSPS_GET_ALS_MODE:
  1030. enable = test_bit(CMC_BIT_ALS, &obj->enable) ? (1) : (0);
  1031. if (copy_to_user(ptr, &enable, sizeof(enable))) {
  1032. err = -EFAULT;
  1033. goto err_out;
  1034. }
  1035. break;
  1036. case ALSPS_GET_ALS_DATA:
  1037. err = cm36686_read_als(obj->client, &obj->als);
  1038. if (err)
  1039. goto err_out;
  1040. dat = cm36686_get_als_value(obj, obj->als);
  1041. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1042. err = -EFAULT;
  1043. goto err_out;
  1044. }
  1045. break;
  1046. case ALSPS_GET_ALS_RAW_DATA:
  1047. err = cm36686_read_als(obj->client, &obj->als);
  1048. if (err)
  1049. goto err_out;
  1050. dat = obj->als;
  1051. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1052. err = -EFAULT;
  1053. goto err_out;
  1054. }
  1055. break;
  1056. /*----------------------------------for factory mode test---------------------------------------*/
  1057. case ALSPS_GET_PS_TEST_RESULT:
  1058. err = cm36686_read_ps(obj->client, &obj->ps);
  1059. if (err)
  1060. goto err_out;
  1061. if (obj->ps > atomic_read(&obj->ps_thd_val_low))
  1062. ps_result = 0;
  1063. else
  1064. ps_result = 1;
  1065. if (copy_to_user(ptr, &ps_result, sizeof(ps_result))) {
  1066. err = -EFAULT;
  1067. goto err_out;
  1068. }
  1069. break;
  1070. case ALSPS_IOCTL_CLR_CALI:
  1071. if (copy_from_user(&dat, ptr, sizeof(dat))) {
  1072. err = -EFAULT;
  1073. goto err_out;
  1074. }
  1075. if (dat == 0)
  1076. obj->ps_cali = 0;
  1077. break;
  1078. case ALSPS_IOCTL_GET_CALI:
  1079. ps_cali = obj->ps_cali;
  1080. if (copy_to_user(ptr, &ps_cali, sizeof(ps_cali))) {
  1081. err = -EFAULT;
  1082. goto err_out;
  1083. }
  1084. break;
  1085. case ALSPS_IOCTL_SET_CALI:
  1086. if (copy_from_user(&ps_cali, ptr, sizeof(ps_cali))) {
  1087. err = -EFAULT;
  1088. goto err_out;
  1089. }
  1090. obj->ps_cali = ps_cali;
  1091. break;
  1092. case ALSPS_SET_PS_THRESHOLD:
  1093. if (copy_from_user(threshold, ptr, sizeof(threshold))) {
  1094. err = -EFAULT;
  1095. goto err_out;
  1096. }
  1097. APS_ERR("%s set threshold high: 0x%x, low: 0x%x\n", __func__, threshold[0],
  1098. threshold[1]);
  1099. atomic_set(&obj->ps_thd_val_high, (threshold[0] + obj->ps_cali));
  1100. atomic_set(&obj->ps_thd_val_low, (threshold[1] + obj->ps_cali)); /* need to confirm */
  1101. set_psensor_threshold(obj->client);
  1102. break;
  1103. case ALSPS_GET_PS_THRESHOLD_HIGH:
  1104. threshold[0] = atomic_read(&obj->ps_thd_val_high) - obj->ps_cali;
  1105. APS_ERR("%s get threshold high: 0x%x\n", __func__, threshold[0]);
  1106. if (copy_to_user(ptr, &threshold[0], sizeof(threshold[0]))) {
  1107. err = -EFAULT;
  1108. goto err_out;
  1109. }
  1110. break;
  1111. case ALSPS_GET_PS_THRESHOLD_LOW:
  1112. threshold[0] = atomic_read(&obj->ps_thd_val_low) - obj->ps_cali;
  1113. APS_ERR("%s get threshold low: 0x%x\n", __func__, threshold[0]);
  1114. if (copy_to_user(ptr, &threshold[0], sizeof(threshold[0]))) {
  1115. err = -EFAULT;
  1116. goto err_out;
  1117. }
  1118. break;
  1119. /*------------------------------------------------------------------------------------------*/
  1120. default:
  1121. APS_ERR("%s not supported = 0x%04x", __func__, cmd);
  1122. err = -ENOIOCTLCMD;
  1123. break;
  1124. }
  1125. err_out:
  1126. return err;
  1127. }
  1128. #ifdef CONFIG_COMPAT
  1129. static long compat_cm36686_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  1130. {
  1131. APS_FUN();
  1132. if (!filp->f_op || !filp->f_op->unlocked_ioctl) {
  1133. APS_ERR("compat_ion_ioctl file has no f_op or no f_op->unlocked_ioctl.\n");
  1134. return -ENOTTY;
  1135. }
  1136. switch (cmd) {
  1137. case COMPAT_ALSPS_SET_PS_MODE:
  1138. case COMPAT_ALSPS_GET_PS_MODE:
  1139. case COMPAT_ALSPS_GET_PS_DATA:
  1140. case COMPAT_ALSPS_GET_PS_RAW_DATA:
  1141. case COMPAT_ALSPS_SET_ALS_MODE:
  1142. case COMPAT_ALSPS_GET_ALS_MODE:
  1143. case COMPAT_ALSPS_GET_ALS_DATA:
  1144. case COMPAT_ALSPS_GET_ALS_RAW_DATA:
  1145. case COMPAT_ALSPS_GET_PS_TEST_RESULT:
  1146. case COMPAT_ALSPS_GET_ALS_TEST_RESULT:
  1147. case COMPAT_ALSPS_GET_PS_THRESHOLD_HIGH:
  1148. case COMPAT_ALSPS_GET_PS_THRESHOLD_LOW:
  1149. case COMPAT_ALSPS_GET_ALS_THRESHOLD_HIGH:
  1150. case COMPAT_ALSPS_GET_ALS_THRESHOLD_LOW:
  1151. case COMPAT_ALSPS_IOCTL_CLR_CALI:
  1152. case COMPAT_ALSPS_IOCTL_GET_CALI:
  1153. case COMPAT_ALSPS_IOCTL_SET_CALI:
  1154. case COMPAT_ALSPS_SET_PS_THRESHOLD:
  1155. case COMPAT_ALSPS_SET_ALS_THRESHOLD:
  1156. case COMPAT_AAL_SET_ALS_MODE:
  1157. case COMPAT_AAL_GET_ALS_MODE:
  1158. case COMPAT_AAL_GET_ALS_DATA:
  1159. return filp->f_op->unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
  1160. default:
  1161. APS_ERR("compat_ion_ioctl : No such command!! 0x%x\n", cmd);
  1162. return -ENOIOCTLCMD;
  1163. }
  1164. }
  1165. #endif
  1166. /********************************************************************/
  1167. /*------------------------------misc device related operation functions------------------------------------*/
  1168. static const struct file_operations cm36686_fops = {
  1169. .owner = THIS_MODULE,
  1170. .open = cm36686_open,
  1171. .release = cm36686_release,
  1172. .unlocked_ioctl = cm36686_unlocked_ioctl,
  1173. #if IS_ENABLED(CONFIG_COMPAT)
  1174. .compat_ioctl = compat_cm36686_unlocked_ioctl,
  1175. #endif
  1176. };
  1177. static struct miscdevice cm36686_device = {
  1178. .minor = MISC_DYNAMIC_MINOR,
  1179. .name = "als_ps",
  1180. .fops = &cm36686_fops,
  1181. };
  1182. /*--------------------------------------------------------------------------------*/
  1183. static int cm36686_init_client(struct i2c_client *client)
  1184. {
  1185. struct cm36686_priv *obj = i2c_get_clientdata(client);
  1186. u8 databuf[3];
  1187. int res = 0;
  1188. APS_FUN();
  1189. databuf[0] = CM36686_REG_ALS_CONF;
  1190. if (1 == obj->hw->polling_mode_als)
  1191. databuf[1] = 0x41; /*0b01000001;*/
  1192. else
  1193. databuf[1] = 0x47; /*0b01000111;*/
  1194. databuf[2] = 0x00; /*0b00000000;*/
  1195. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1196. if (res <= 0) {
  1197. APS_ERR("i2c_master_send function err\n");
  1198. goto EXIT_ERR;
  1199. }
  1200. APS_LOG("cm36686 ps CM36686_REG_ALS_CONF command!\n");
  1201. databuf[0] = CM36686_REG_PS_CONF1_2;
  1202. databuf[1] = 0x63; /*0b01100011;*/
  1203. if (1 == obj->hw->polling_mode_ps)
  1204. databuf[2] = 0x08; /*0b00001000;*/
  1205. else
  1206. databuf[2] = 0x0B; /*0b00001011;*/
  1207. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1208. if (res <= 0) {
  1209. APS_ERR("i2c_master_send function err\n");
  1210. goto EXIT_ERR;
  1211. }
  1212. APS_LOG("cm36686 ps CM36686_REG_PS_CONF1_2 command!\n");
  1213. databuf[0] = CM36686_REG_PS_CONF3_MS;
  1214. databuf[1] = 0x14; /*0b00010100;*/
  1215. databuf[2] = 0x02; /*0b00000010;*/
  1216. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1217. if (res <= 0) {
  1218. APS_ERR("i2c_master_send function err\n");
  1219. goto EXIT_ERR;
  1220. }
  1221. APS_LOG("cm36686 ps CM36686_REG_PS_CONF3_MS command!\n");
  1222. databuf[0] = CM36686_REG_PS_CANC; /* value need to confirm */
  1223. databuf[1] = 0x00;
  1224. databuf[2] = 0x00;
  1225. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1226. if (res <= 0) {
  1227. APS_ERR("i2c_master_send function err\n");
  1228. goto EXIT_ERR;
  1229. }
  1230. APS_LOG("cm36686 ps CM36686_REG_PS_CANC command!\n");
  1231. if (0 == obj->hw->polling_mode_als) {
  1232. databuf[0] = CM36686_REG_ALS_THDH;
  1233. databuf[1] = 0x00;
  1234. databuf[2] = atomic_read(&obj->als_thd_val_high);
  1235. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1236. if (res <= 0) {
  1237. APS_ERR("i2c_master_send function err\n");
  1238. goto EXIT_ERR;
  1239. }
  1240. databuf[0] = CM36686_REG_ALS_THDL;
  1241. databuf[1] = 0x00;
  1242. databuf[2] = atomic_read(&obj->als_thd_val_low); /* threshold value need to confirm */
  1243. res = CM36686_i2c_master_operate(client, databuf, 0x3, I2C_FLAG_WRITE);
  1244. if (res <= 0) {
  1245. APS_ERR("i2c_master_send function err\n");
  1246. goto EXIT_ERR;
  1247. }
  1248. }
  1249. if (0 == obj->hw->polling_mode_ps) {
  1250. databuf[0] = CM36686_REG_PS_THDL;
  1251. databuf[1] = atomic_read(&obj->ps_thd_val_low);
  1252. databuf[2] = atomic_read(&obj->ps_thd_val_low) >> 8;
  1253. res = CM36686_i2c_master_operate(client, databuf, 3, I2C_FLAG_WRITE);
  1254. if (res <= 0) {
  1255. APS_ERR("i2c_master_send function err\n");
  1256. goto EXIT_ERR;
  1257. }
  1258. databuf[0] = CM36686_REG_PS_THDH;
  1259. databuf[1] = atomic_read(&obj->ps_thd_val_high);
  1260. databuf[2] = atomic_read(&obj->ps_thd_val_high) >> 8;
  1261. res = CM36686_i2c_master_operate(client, databuf, 3, I2C_FLAG_WRITE);
  1262. if (res <= 0) {
  1263. APS_ERR("i2c_master_send function err\n");
  1264. goto EXIT_ERR;
  1265. }
  1266. }
  1267. res = cm36686_setup_eint(client);
  1268. if (res != 0) {
  1269. APS_ERR("setup eint: %d\n", res);
  1270. return res;
  1271. }
  1272. return CM36686_SUCCESS;
  1273. EXIT_ERR:
  1274. APS_ERR("init dev: %d\n", res);
  1275. return res;
  1276. }
  1277. /*--------------------------------------------------------------------------------*/
  1278. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL */
  1279. static int als_open_report_data(int open)
  1280. {
  1281. /* should queuq work to report event if is_report_input_direct=true */
  1282. return 0;
  1283. }
  1284. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL */
  1285. static int als_enable_nodata(int en)
  1286. {
  1287. int res = 0;
  1288. APS_LOG("cm36686_obj als enable value = %d\n", en);
  1289. mutex_lock(&cm36686_mutex);
  1290. if (en)
  1291. set_bit(CMC_BIT_ALS, &cm36686_obj->enable);
  1292. else
  1293. clear_bit(CMC_BIT_ALS, &cm36686_obj->enable);
  1294. mutex_unlock(&cm36686_mutex);
  1295. if (!cm36686_obj) {
  1296. APS_ERR("cm36686_obj is null!!\n");
  1297. return -1;
  1298. }
  1299. res = cm36686_enable_als(cm36686_obj->client, en);
  1300. if (res) {
  1301. APS_ERR("als_enable_nodata is failed!!\n");
  1302. return -1;
  1303. }
  1304. return 0;
  1305. }
  1306. static int als_set_delay(u64 ns)
  1307. {
  1308. return 0;
  1309. }
  1310. static int als_get_data(int *value, int *status)
  1311. {
  1312. int err = 0;
  1313. struct cm36686_priv *obj = NULL;
  1314. if (!cm36686_obj) {
  1315. APS_ERR("cm36686_obj is null!!\n");
  1316. return -1;
  1317. }
  1318. obj = cm36686_obj;
  1319. err = cm36686_read_als(obj->client, &obj->als);
  1320. if (err) {
  1321. err = -1;
  1322. } else {
  1323. *value = cm36686_get_als_value(obj, obj->als);
  1324. if (*value < 0)
  1325. err = -1;
  1326. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1327. }
  1328. return err;
  1329. }
  1330. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL */
  1331. static int ps_open_report_data(int open)
  1332. {
  1333. /* should queuq work to report event if is_report_input_direct=true */
  1334. return 0;
  1335. }
  1336. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL */
  1337. static int ps_enable_nodata(int en)
  1338. {
  1339. int res = 0;
  1340. APS_LOG("cm36686_obj als enable value = %d\n", en);
  1341. mutex_lock(&cm36686_mutex);
  1342. if (en)
  1343. set_bit(CMC_BIT_PS, &cm36686_obj->enable);
  1344. else
  1345. clear_bit(CMC_BIT_PS, &cm36686_obj->enable);
  1346. mutex_unlock(&cm36686_mutex);
  1347. if (!cm36686_obj) {
  1348. APS_ERR("cm36686_obj is null!!\n");
  1349. return -1;
  1350. }
  1351. res = cm36686_enable_ps(cm36686_obj->client, en);
  1352. if (res) {
  1353. APS_ERR("als_enable_nodata is failed!!\n");
  1354. return -1;
  1355. }
  1356. return 0;
  1357. }
  1358. static int ps_set_delay(u64 ns)
  1359. {
  1360. return 0;
  1361. }
  1362. static int ps_get_data(int *value, int *status)
  1363. {
  1364. int err = 0;
  1365. if (!cm36686_obj) {
  1366. APS_ERR("cm36686_obj is null!!\n");
  1367. return -1;
  1368. }
  1369. err = cm36686_read_ps(cm36686_obj->client, &cm36686_obj->ps);
  1370. if (err) {
  1371. err = -1;
  1372. } else {
  1373. *value = cm36686_get_ps_value(cm36686_obj, cm36686_obj->ps);
  1374. if (*value < 0)
  1375. err = -1;
  1376. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1377. }
  1378. return err;
  1379. }
  1380. /*-----------------------------------i2c operations----------------------------------*/
  1381. static int cm36686_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  1382. {
  1383. struct cm36686_priv *obj;
  1384. int err = 0;
  1385. struct als_control_path als_ctl = { 0 };
  1386. struct als_data_path als_data = { 0 };
  1387. struct ps_control_path ps_ctl = { 0 };
  1388. struct ps_data_path ps_data = { 0 };
  1389. APS_FUN();
  1390. obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  1391. if (!obj) {
  1392. err = -ENOMEM;
  1393. goto exit;
  1394. }
  1395. memset(obj, 0, sizeof(*obj));
  1396. cm36686_obj = obj;
  1397. obj->hw = hw;
  1398. INIT_WORK(&obj->eint_work, cm36686_eint_work);
  1399. obj->client = client;
  1400. i2c_set_clientdata(client, obj);
  1401. /*-----------------------------value need to be confirmed-----------------------------------------*/
  1402. atomic_set(&obj->als_debounce, 200);
  1403. atomic_set(&obj->als_deb_on, 0);
  1404. #ifdef CONFIG_64BIT
  1405. atomic64_set(&obj->als_deb_end, 0);
  1406. #else
  1407. atomic_set(&obj->als_deb_end, 0);
  1408. #endif
  1409. atomic_set(&obj->ps_debounce, 200);
  1410. atomic_set(&obj->ps_deb_on, 0);
  1411. #ifdef CONFIG_64BIT
  1412. atomic64_set(&obj->ps_deb_end, 0);
  1413. #else
  1414. atomic_set(&obj->ps_deb_end, 0);
  1415. #endif
  1416. atomic_set(&obj->ps_mask, 0);
  1417. atomic_set(&obj->als_suspend, 0);
  1418. atomic_set(&obj->als_cmd_val, 0xDF);
  1419. atomic_set(&obj->ps_cmd_val, 0xC1);
  1420. atomic_set(&obj->ps_thd_val_high, obj->hw->ps_threshold_high);
  1421. atomic_set(&obj->ps_thd_val_low, obj->hw->ps_threshold_low);
  1422. atomic_set(&obj->als_thd_val_high, obj->hw->als_threshold_high);
  1423. atomic_set(&obj->als_thd_val_low, obj->hw->als_threshold_low);
  1424. atomic_set(&obj->init_done, 0);
  1425. obj->irq_node = of_find_compatible_node(NULL, NULL, "mediatek, ALS-eint");
  1426. obj->enable = 0;
  1427. obj->pending_intr = 0;
  1428. obj->ps_cali = 0;
  1429. obj->als_level_num = sizeof(obj->hw->als_level) / sizeof(obj->hw->als_level[0]);
  1430. obj->als_value_num = sizeof(obj->hw->als_value) / sizeof(obj->hw->als_value[0]);
  1431. /*-----------------------------value need to be confirmed-----------------------------------------*/
  1432. BUG_ON(sizeof(obj->als_level) != sizeof(obj->hw->als_level));
  1433. memcpy(obj->als_level, obj->hw->als_level, sizeof(obj->als_level));
  1434. BUG_ON(sizeof(obj->als_value) != sizeof(obj->hw->als_value));
  1435. memcpy(obj->als_value, obj->hw->als_value, sizeof(obj->als_value));
  1436. atomic_set(&obj->i2c_retry, 3);
  1437. clear_bit(CMC_BIT_ALS, &obj->enable);
  1438. clear_bit(CMC_BIT_PS, &obj->enable);
  1439. cm36686_i2c_client = client;
  1440. err = cm36686_init_client(client);
  1441. if (err)
  1442. goto exit_init_failed;
  1443. APS_LOG("cm36686_init_client() OK!\n");
  1444. err = misc_register(&cm36686_device);
  1445. if (err) {
  1446. APS_ERR("cm36686_device register failed\n");
  1447. goto exit_misc_device_register_failed;
  1448. }
  1449. als_ctl.is_use_common_factory = false;
  1450. ps_ctl.is_use_common_factory = false;
  1451. APS_LOG("cm36686_device misc_register OK!\n");
  1452. /*------------------------cm36686 attribute file for debug--------------------------------------*/
  1453. err = cm36686_create_attr(&(cm36686_init_info.platform_diver_addr->driver));
  1454. if (err) {
  1455. APS_ERR("create attribute err = %d\n", err);
  1456. goto exit_create_attr_failed;
  1457. }
  1458. /*------------------------cm36686 attribute file for debug--------------------------------------*/
  1459. als_ctl.open_report_data = als_open_report_data;
  1460. als_ctl.enable_nodata = als_enable_nodata;
  1461. als_ctl.set_delay = als_set_delay;
  1462. als_ctl.is_report_input_direct = false;
  1463. als_ctl.is_support_batch = false;
  1464. err = als_register_control_path(&als_ctl);
  1465. if (err) {
  1466. APS_ERR("register fail = %d\n", err);
  1467. goto exit_sensor_obj_attach_fail;
  1468. }
  1469. als_data.get_data = als_get_data;
  1470. als_data.vender_div = 100;
  1471. err = als_register_data_path(&als_data);
  1472. if (err) {
  1473. APS_ERR("tregister fail = %d\n", err);
  1474. goto exit_sensor_obj_attach_fail;
  1475. }
  1476. ps_ctl.open_report_data = ps_open_report_data;
  1477. ps_ctl.enable_nodata = ps_enable_nodata;
  1478. ps_ctl.set_delay = ps_set_delay;
  1479. ps_ctl.is_report_input_direct = false;
  1480. ps_ctl.is_support_batch = false;
  1481. ps_ctl.is_polling_mode = obj->hw->polling_mode_ps;
  1482. err = ps_register_control_path(&ps_ctl);
  1483. if (err) {
  1484. APS_ERR("register fail = %d\n", err);
  1485. goto exit_sensor_obj_attach_fail;
  1486. }
  1487. ps_data.get_data = ps_get_data;
  1488. ps_data.vender_div = 100;
  1489. err = ps_register_data_path(&ps_data);
  1490. if (err) {
  1491. APS_ERR("tregister fail = %d\n", err);
  1492. goto exit_sensor_obj_attach_fail;
  1493. }
  1494. err = batch_register_support_info(ID_LIGHT, als_ctl.is_support_batch, 1, 0);
  1495. if (err)
  1496. APS_ERR("register light batch support err = %d\n", err);
  1497. err = batch_register_support_info(ID_PROXIMITY, ps_ctl.is_support_batch, 1, 0);
  1498. if (err)
  1499. APS_ERR("register proximity batch support err = %d\n", err);
  1500. cm36686_init_flag = 0;
  1501. APS_LOG("%s: OK\n", __func__);
  1502. return 0;
  1503. exit_create_attr_failed:
  1504. exit_sensor_obj_attach_fail:
  1505. exit_misc_device_register_failed:
  1506. misc_deregister(&cm36686_device);
  1507. exit_init_failed:
  1508. kfree(obj);
  1509. exit:
  1510. cm36686_i2c_client = NULL;
  1511. APS_ERR("%s: err = %d\n", __func__, err);
  1512. cm36686_init_flag = -1;
  1513. return err;
  1514. }
  1515. static int cm36686_i2c_remove(struct i2c_client *client)
  1516. {
  1517. int err;
  1518. /*------------------------cm36686 attribute file for debug--------------------------------------*/
  1519. err = cm36686_delete_attr(&(cm36686_init_info.platform_diver_addr->driver));
  1520. if (err)
  1521. APS_ERR("cm36686_delete_attr fail: %d\n", err);
  1522. /*----------------------------------------------------------------------------------------*/
  1523. err = misc_deregister(&cm36686_device);
  1524. if (err)
  1525. APS_ERR("misc_deregister fail: %d\n", err);
  1526. cm36686_i2c_client = NULL;
  1527. i2c_unregister_device(client);
  1528. kfree(i2c_get_clientdata(client));
  1529. return 0;
  1530. }
  1531. static int cm36686_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
  1532. {
  1533. strcpy(info->type, CM36686_DEV_NAME);
  1534. return 0;
  1535. }
  1536. static int cm36686_i2c_suspend(struct i2c_client *client, pm_message_t msg)
  1537. {
  1538. struct cm36686_priv *obj = i2c_get_clientdata(client);
  1539. int err;
  1540. APS_FUN();
  1541. if (!obj) {
  1542. APS_ERR("null pointer!!\n");
  1543. return 0;
  1544. }
  1545. atomic_set(&obj->als_suspend, 1);
  1546. err = cm36686_enable_als(obj->client, 0);
  1547. if (err)
  1548. APS_ERR("disable als fail: %d\n", err);
  1549. return 0;
  1550. }
  1551. static int cm36686_i2c_resume(struct i2c_client *client)
  1552. {
  1553. struct cm36686_priv *obj = i2c_get_clientdata(client);
  1554. int err;
  1555. struct hwm_sensor_data sensor_data;
  1556. memset(&sensor_data, 0, sizeof(sensor_data));
  1557. APS_FUN();
  1558. if (!obj) {
  1559. APS_ERR("null pointer!!\n");
  1560. return 0;
  1561. }
  1562. atomic_set(&obj->als_suspend, 0);
  1563. if (test_bit(CMC_BIT_ALS, &obj->enable)) {
  1564. err = cm36686_enable_als(obj->client, 1);
  1565. if (err)
  1566. APS_ERR("enable als fail: %d\n", err);
  1567. }
  1568. return 0;
  1569. }
  1570. /*----------------------------------------------------------------------------*/
  1571. /*----------------------------------------------------------------------------*/
  1572. static int cm36686_remove(void)
  1573. {
  1574. cm36686_power(hw, 0);
  1575. i2c_del_driver(&cm36686_i2c_driver);
  1576. return 0;
  1577. }
  1578. /*----------------------------------------------------------------------------*/
  1579. static int cm36686_local_init(void)
  1580. {
  1581. cm36686_power(hw, 1);
  1582. if (i2c_add_driver(&cm36686_i2c_driver)) {
  1583. APS_ERR("add driver error\n");
  1584. return -1;
  1585. }
  1586. if (-1 == cm36686_init_flag)
  1587. return -1;
  1588. return 0;
  1589. }
  1590. /*----------------------------------------------------------------------------*/
  1591. static int __init cm36686_init(void)
  1592. {
  1593. const char *name = "mediatek,CM36686";
  1594. hw = get_alsps_dts_func(name, hw);
  1595. if (!hw) {
  1596. APS_ERR("get_alsps_dts_func fail\n");
  1597. return 0;
  1598. }
  1599. alsps_driver_add(&cm36686_init_info);
  1600. return 0;
  1601. }
  1602. /*----------------------------------------------------------------------------*/
  1603. static void __exit cm36686_exit(void)
  1604. {
  1605. APS_FUN();
  1606. }
  1607. /*----------------------------------------------------------------------------*/
  1608. module_init(cm36686_init);
  1609. module_exit(cm36686_exit);
  1610. /*----------------------------------------------------------------------------*/
  1611. MODULE_AUTHOR("andrew yang");
  1612. MODULE_DESCRIPTION("cm36686 driver");
  1613. MODULE_LICENSE("GPL");