taos_tmd3782.c 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905
  1. /*
  2. * Copyright (c) 2010 SAMSUNG
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (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. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  17. * MA 02110-1301, USA.
  18. */
  19. #include <linux/module.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/irq.h>
  22. #include <linux/i2c.h>
  23. #include <linux/fs.h>
  24. #include <linux/errno.h>
  25. #include <linux/device.h>
  26. #include <linux/delay.h>
  27. #include <linux/miscdevice.h>
  28. #include <linux/platform_device.h>
  29. #include <linux/leds.h>
  30. #include <linux/gpio.h>
  31. #include <linux/wakelock.h>
  32. #include <linux/slab.h>
  33. #include <linux/input.h>
  34. #include <linux/workqueue.h>
  35. #include <linux/uaccess.h>
  36. #include <linux/of_gpio.h>
  37. #include <linux/regulator/consumer.h>
  38. #include <linux/i2c/taos_tmd3782.h>
  39. #include "sensors_core.h"
  40. /* Note about power vs enable/disable:
  41. * The chip has two functions, proximity and ambient light sensing.
  42. * There is no separate power enablement to the two functions (unlike
  43. * the Capella CM3602/3623).
  44. * This module implements two drivers: /dev/proximity and /dev/light.
  45. * When either driver is enabled (via sysfs attributes), we give power
  46. * to the chip. When both are disabled, we remove power from the chip.
  47. * In suspend, we remove power if light is disabled but not if proximity is
  48. * enabled (proximity is allowed to wakeup from suspend).
  49. *
  50. * There are no ioctls for either driver interfaces. Output is via
  51. * input device framework and control via sysfs attributes.
  52. */
  53. /* taos debug */
  54. #define MODULE_NAME_PROX "proximity_sensor"
  55. #define taos_dbgmsg(str, args...) pr_info("%s: " str, __func__, ##args)
  56. #define TAOS_DEBUG
  57. #ifdef TAOS_DEBUG
  58. #define gprintk(fmt, x...) \
  59. printk(KERN_INFO "%s(%d):" fmt, __func__, __LINE__, ## x)
  60. #else
  61. #define gprintk(x...) do { } while (0)
  62. #endif
  63. #define VENDOR_NAME "TAOS"
  64. #define CHIP_NAME "TMD3782"
  65. #define CHIP_ID 0x69
  66. /* sensor type */
  67. #define LIGHT 0
  68. #define PROXIMITY 1
  69. #define ALL 2
  70. enum {
  71. LIGHT_ENABLED = BIT(0),
  72. PROXIMITY_ENABLED = BIT(1),
  73. };
  74. enum {
  75. STATE_CLOSE = 0,
  76. STATE_FAR = 1,
  77. };
  78. enum {
  79. OFF = 0,
  80. ON = 1,
  81. };
  82. #define Atime_ms 504 //50.4 ms
  83. #ifdef CONFIG_SEC_RUBENS_PROJECT
  84. #define DGF 600
  85. #define R_Coef1 (260)
  86. #define G_Coef1 (1000)
  87. #define B_Coef1 (20)
  88. #define CT_Coef1 (3200)
  89. #define CT_Offset1 (1840)
  90. #elif defined(CONFIG_SEC_S_PROJECT)
  91. #define Atime_ms 504 //50.4 ms
  92. #define DGF 642
  93. #define R_Coef1 (330)
  94. #define G_Coef1 (1000)
  95. #define B_Coef1 (150)
  96. #define CT_Coef1 (3210)
  97. #define CT_Offset1 (1788)
  98. #else
  99. #define DGF 625
  100. #define R_Coef1 (-580)
  101. #define G_Coef1 (1010)
  102. #define B_Coef1 (80)
  103. #define CT_Coef1 (2855)
  104. #define CT_Offset1 (1973)
  105. #endif
  106. #define IR_R_Coef1 (-1)
  107. #define IR_G_Coef1 (109)
  108. #define IR_B_Coef1 (-29)
  109. #define IR_C_Coef1 (57)
  110. #define IR_Coef1 (38)
  111. #define INTEGRATION_CYCLE 240
  112. #define ADC_BUFFER_NUM 6
  113. #define PROX_AVG_COUNT 40
  114. #define MAX_LUX 150000
  115. #define TAOS_PROX_MAX 1023
  116. #define TAOS_PROX_MIN 0
  117. #define OFFSET_ARRAY_LENGTH 10
  118. #define OFFSET_FILE_PATH "/efs/prox_cal"
  119. #define CAL_SKIP_ADC 325
  120. #define CAL_FAIL_ADC 400
  121. #ifdef CONFIG_PROX_WINDOW_TYPE
  122. #define WINDOW_TYPE_FILE_PATH "/sys/class/sec/sec_touch_ic/window_type"
  123. #endif
  124. /* driver data */
  125. struct taos_data {
  126. struct i2c_client *i2c_client;
  127. struct taos_platform_data *pdata;
  128. struct input_dev *proximity_input_dev;
  129. struct input_dev *light_input_dev;
  130. struct device *light_dev;
  131. struct device *proximity_dev;
  132. struct work_struct work_light;
  133. struct work_struct work_prox;
  134. struct work_struct work_prox_avg;
  135. struct mutex prox_mutex;
  136. struct mutex power_lock;
  137. struct wake_lock prx_wake_lock;
  138. struct hrtimer timer;
  139. struct hrtimer prox_avg_timer;
  140. struct workqueue_struct *wq;
  141. struct workqueue_struct *wq_avg;
  142. ktime_t light_poll_delay;
  143. ktime_t prox_polling_time;
  144. u8 power_state;
  145. int irq;
  146. bool adc_buf_initialized;
  147. int adc_value_buf[ADC_BUFFER_NUM];
  148. int adc_index_count;
  149. int avg[3];
  150. int prox_avg_enable;
  151. s32 clrdata;
  152. s32 reddata;
  153. s32 grndata;
  154. s32 bludata;
  155. s32 irdata;
  156. int lux;
  157. /* Auto Calibration */
  158. u16 offset_value;
  159. int cal_result;
  160. int threshold_high;
  161. int threshold_low;
  162. int proximity_value;
  163. bool set_manual_thd;
  164. #ifdef CONFIG_PROX_WINDOW_TYPE
  165. char windowtype[2];
  166. #endif
  167. #ifdef CONFIG_SEC_S_PROJECT
  168. /* Regulator */
  169. struct regulator *vdd_3p3;
  170. #else
  171. struct regulator *vdd_2p85;
  172. struct regulator *leda_2p8;
  173. struct regulator *lvs1_1p8;
  174. #endif
  175. };
  176. static void taos_thresh_set(struct taos_data *taos);
  177. static int proximity_get_adc(struct taos_data *taos);
  178. static int lightsensor_get_adcvalue(struct taos_data *taos);
  179. static int proximity_open_offset(struct taos_data *data);
  180. static int proximity_adc_read(struct taos_data *taos);
  181. #ifdef CONFIG_PROX_WINDOW_TYPE
  182. static int proximity_open_window_type(struct taos_data *data);
  183. #endif
  184. static void sensor_power_on_vdd(struct taos_data *info, int onoff)
  185. {
  186. #ifdef CONFIG_SEC_S_PROJECT
  187. info->vdd_3p3 = regulator_get(&info->i2c_client->dev, "max77826_ldo12");
  188. if (IS_ERR(info->vdd_3p3)) {
  189. pr_err("%s - regulator_get fail\n", __func__);
  190. return ;
  191. }
  192. pr_info("%s - onoff = %d\n", __func__, onoff);
  193. if (onoff) {
  194. gpio_set_value(info->pdata->enable,1);
  195. regulator_set_voltage(info->vdd_3p3, 3300000, 3300000);
  196. regulator_enable(info->vdd_3p3);
  197. } else {
  198. regulator_disable(info->vdd_3p3);
  199. gpio_set_value(info->pdata->enable,0);
  200. }
  201. regulator_put(info->vdd_3p3);
  202. msleep(30);
  203. return ;
  204. #else
  205. int ret;
  206. if (info->vdd_2p85 == NULL) {
  207. info->vdd_2p85 =regulator_get(&info->i2c_client->dev, "8226_l19");
  208. if (IS_ERR(info->vdd_2p85)){
  209. pr_err("%s: regulator_get failed for 8226_l19\n", __func__);
  210. return ;
  211. }
  212. ret = regulator_set_voltage(info->vdd_2p85, 2850000, 2850000);
  213. if (ret)
  214. pr_err("%s: error vsensor_2p85 setting voltage ret=%d\n",__func__, ret);
  215. }
  216. if (info->leda_2p8 == NULL) {
  217. info->leda_2p8 =regulator_get(&info->i2c_client->dev, "8226_l15");
  218. if (IS_ERR(info->leda_2p8)){
  219. pr_err("%s: regulator_get failed for 8226_l15\n", __func__);
  220. return ;
  221. }
  222. ret = regulator_set_voltage(info->leda_2p8, 2800000, 2800000);
  223. if (ret)
  224. pr_err("%s: error leda_2p8 setting voltage ret=%d\n",__func__, ret);
  225. }
  226. if (!info->lvs1_1p8) {
  227. info->lvs1_1p8 = regulator_get(&info->i2c_client->dev, "8226_lvs1");
  228. if(!info->lvs1_1p8){
  229. pr_err("%s: regulator_get for 8226_lvs1 failed\n", __func__);
  230. return ;
  231. }
  232. }
  233. if (onoff == 1) {
  234. ret = regulator_enable(info->vdd_2p85);
  235. if (ret)
  236. pr_err("%s: error enablinig regulator info->vdd_2p85\n", __func__);
  237. ret = regulator_enable(info->leda_2p8);
  238. if (ret)
  239. pr_err("%s: error enablinig regulator info->leda_2p8\n", __func__);
  240. ret = regulator_enable(info->lvs1_1p8);
  241. if (ret)
  242. pr_err("%s: Failed to enable regulator lvs1_1p8.\n",__func__);
  243. }
  244. else if (onoff == 0) {
  245. if (regulator_is_enabled(info->vdd_2p85)) {
  246. ret = regulator_disable(info->vdd_2p85);
  247. if (ret)
  248. pr_err("%s: error vdd_2p85 disabling regulator\n",__func__);
  249. }
  250. if (regulator_is_enabled(info->leda_2p8)) {
  251. ret = regulator_disable(info->leda_2p8);
  252. if (ret)
  253. pr_err("%s: error leda_2p8 disabling regulator\n",__func__);
  254. }
  255. if (regulator_is_enabled(info->lvs1_1p8)) {
  256. ret = regulator_disable(info->lvs1_1p8);
  257. if (ret)
  258. pr_err("%s: error lvs1_1p8 disabling regulator\n",__func__);
  259. }
  260. }
  261. msleep(30);
  262. return;
  263. #endif
  264. }
  265. static int opt_i2c_write(struct taos_data *taos, u8 reg, u8 *val)
  266. {
  267. int ret;
  268. ret = i2c_smbus_write_byte_data(taos->i2c_client,
  269. (CMD_REG | reg), *val);
  270. return ret;
  271. }
  272. static int opt_i2c_read(struct taos_data *taos, u8 reg , u8 *val)
  273. {
  274. int ret;
  275. i2c_smbus_write_byte(taos->i2c_client, (CMD_REG | reg));
  276. ret = i2c_smbus_read_byte(taos->i2c_client);
  277. *val = ret;
  278. return ret;
  279. }
  280. static int opt_i2c_write_command(struct taos_data *taos, u8 val)
  281. {
  282. int ret;
  283. ret = i2c_smbus_write_byte(taos->i2c_client, val);
  284. gprintk("[TAOS Command] val=[0x%x] - ret=[0x%x]\n", val, ret);
  285. return ret;
  286. }
  287. static int proximity_get_adc(struct taos_data *taos)
  288. {
  289. int adc = 0;
  290. adc = i2c_smbus_read_word_data(taos->i2c_client,
  291. CMD_REG | PRX_LO);
  292. if (adc < taos->pdata->prox_rawdata_trim)
  293. return TAOS_PROX_MIN;
  294. if (adc > TAOS_PROX_MAX)
  295. adc = TAOS_PROX_MAX;
  296. return adc - taos->pdata->prox_rawdata_trim;
  297. }
  298. static int taos_proximity_get_threshold(struct taos_data *taos, u8 buf)
  299. {
  300. u16 threshold;
  301. threshold = i2c_smbus_read_word_data(taos->i2c_client,(CMD_REG | buf));
  302. if ((threshold == 0xFFFF) || (threshold == 0))
  303. return (int)threshold;
  304. return (int)threshold - taos->pdata->prox_rawdata_trim;
  305. }
  306. static void taos_thresh_set(struct taos_data *taos)
  307. {
  308. int i = 0;
  309. int ret = 0;
  310. u8 prox_int_thresh[4] = {0,};
  311. u16 trim = (u16)taos->pdata->prox_rawdata_trim;
  312. /* Setting for proximity interrupt */
  313. if (taos->proximity_value == STATE_CLOSE) {
  314. prox_int_thresh[0] = ((u16)taos->threshold_low+trim) & 0xFF;
  315. prox_int_thresh[1] = ((taos->threshold_low+trim) >> 8) & 0xFF;
  316. prox_int_thresh[2] = (0xFFFF) & 0xFF;
  317. prox_int_thresh[3] = (0xFFFF >> 8) & 0xFF;
  318. } else {
  319. prox_int_thresh[0] = (0x0000) & 0xFF;
  320. prox_int_thresh[1] = (0x0000 >> 8) & 0xFF;
  321. prox_int_thresh[2] = ((u16)taos->threshold_high+trim) & 0xff;
  322. prox_int_thresh[3] = (((u16)taos->threshold_high+trim) >> 8) & 0xff;
  323. }
  324. for (i = 0; i < 4; i++) {
  325. ret = opt_i2c_write(taos,
  326. (CMD_REG|(PRX_MINTHRESHLO + i)),
  327. &prox_int_thresh[i]);
  328. if (ret < 0)
  329. gprintk("opt_i2c_write failed, err = %d\n", ret);
  330. }
  331. }
  332. static int taos_chip_on(struct taos_data *taos)
  333. {
  334. int ret = 0;
  335. u8 temp_val;
  336. u8 reg_cntrl;
  337. sensor_power_on_vdd(taos,ON);
  338. temp_val = CNTL_PWRON;
  339. ret = opt_i2c_write(taos, (CMD_REG|CNTRL), &temp_val);
  340. if (ret < 0) {
  341. gprintk("opt_i2c_write to clr ctrl reg failed\n");
  342. }
  343. temp_val = taos->pdata->als_time;
  344. ret = opt_i2c_write(taos, (CMD_REG|ALS_TIME), &temp_val);
  345. if (ret < 0) {
  346. gprintk("opt_i2c_write to als time reg failed\n");
  347. }
  348. temp_val = 0xff;
  349. ret = opt_i2c_write(taos, (CMD_REG|WAIT_TIME), &temp_val);
  350. if (ret < 0) {
  351. gprintk("opt_i2c_write to wait time reg failed\n");
  352. }
  353. temp_val = taos->pdata->intr_filter;
  354. ret = opt_i2c_write(taos, (CMD_REG|INTERRUPT), &temp_val);
  355. if (ret < 0) {
  356. gprintk("opt_i2c_write to interrupt reg failed\n");
  357. }
  358. temp_val = 0x0;
  359. ret = opt_i2c_write(taos, (CMD_REG|PRX_CFG), &temp_val);
  360. if (ret < 0) {
  361. gprintk("opt_i2c_write to prox cfg reg failed\n");
  362. }
  363. temp_val = taos->pdata->prox_pulsecnt;
  364. ret = opt_i2c_write(taos, (CMD_REG|PRX_COUNT), &temp_val);
  365. if (ret < 0) {
  366. gprintk("opt_i2c_write to prox cnt reg failed\n");
  367. }
  368. temp_val = taos->pdata->als_gain;
  369. ret = opt_i2c_write(taos, (CMD_REG|GAIN), &temp_val);
  370. if (ret < 0) {
  371. gprintk("opt_i2c_write to prox gain reg failed\n");
  372. }
  373. reg_cntrl = CNTL_INTPROXPON_ENBL;
  374. ret = opt_i2c_write(taos, (CMD_REG|CNTRL), &reg_cntrl);
  375. if (ret < 0) {
  376. gprintk("opt_i2c_write to ctrl reg failed\n");
  377. }
  378. return ret;
  379. }
  380. static int taos_chip_off(struct taos_data *taos)
  381. {
  382. int ret = 0;
  383. u8 reg_cntrl;
  384. reg_cntrl = CNTL_REG_CLEAR;
  385. ret = opt_i2c_write(taos, (CMD_REG | CNTRL), &reg_cntrl);
  386. if (ret < 0) {
  387. gprintk("opt_i2c_write to ctrl reg failed\n");
  388. return ret;
  389. }
  390. sensor_power_on_vdd(taos,OFF);
  391. return ret;
  392. }
  393. static int taos_get_cct(struct taos_data *taos)
  394. {
  395. int bp1 = taos->bludata - taos->irdata;
  396. int rp1 = taos->reddata - taos->irdata;
  397. int cct = 0;
  398. if(rp1 != 0)
  399. cct = CT_Coef1 * bp1 / rp1 + CT_Offset1;
  400. return cct;
  401. }
  402. static int taos_get_lux(struct taos_data *taos)
  403. {
  404. s32 rp1, gp1, bp1;
  405. s32 clrdata = 0;
  406. s32 reddata = 0;
  407. s32 grndata = 0;
  408. s32 bludata = 0;
  409. s32 calculated_lux = 0;
  410. u8 reg_gain = 0x0;
  411. u16 temp_gain = 0x0;
  412. int gain = 1;
  413. int ret = 0;
  414. temp_gain = i2c_smbus_read_word_data(taos->i2c_client,
  415. (CMD_REG | GAIN));
  416. reg_gain = temp_gain & 0xff;
  417. clrdata = i2c_smbus_read_word_data(taos->i2c_client,
  418. (CMD_REG | CLR_CHAN0LO));
  419. reddata = i2c_smbus_read_word_data(taos->i2c_client,
  420. (CMD_REG | RED_CHAN1LO));
  421. grndata = i2c_smbus_read_word_data(taos->i2c_client,
  422. (CMD_REG | GRN_CHAN1LO));
  423. bludata = i2c_smbus_read_word_data(taos->i2c_client,
  424. (CMD_REG | BLU_CHAN1LO));
  425. taos->clrdata = clrdata;
  426. taos->reddata = reddata;
  427. taos->grndata = grndata;
  428. taos->bludata = bludata;
  429. switch(reg_gain & 0x03)
  430. {
  431. case 0x00:
  432. gain = 1;
  433. break;
  434. case 0x01:
  435. gain = 4;
  436. break;
  437. case 0x02:
  438. gain = 16;
  439. break;
  440. /* case 0x03:
  441. gain = 64;
  442. break;*/
  443. default:
  444. break;
  445. }
  446. if(gain == 1 && clrdata < 25)
  447. {
  448. reg_gain = 0x22;
  449. ret = opt_i2c_write(taos, (CMD_REG | GAIN), &reg_gain);
  450. if (ret < 0)
  451. gprintk("opt_i2c_write failed, err = %d\n", ret);
  452. return taos->lux;
  453. }
  454. else if(gain ==16 && clrdata > 15000)
  455. {
  456. reg_gain = 0x20;
  457. ret = opt_i2c_write(taos, (CMD_REG | GAIN), &reg_gain);
  458. if (ret < 0)
  459. gprintk("opt_i2c_write failed, err = %d\n", ret);
  460. return taos->lux;
  461. }
  462. if ((clrdata >= 18500) && (gain == 1))
  463. {
  464. calculated_lux = MAX_LUX;
  465. return calculated_lux;
  466. }
  467. /* calculate lux */
  468. #if defined(CONFIG_SEC_RUBENS_PROJECT) || defined(CONFIG_SEC_S_PROJECT)
  469. taos->irdata = (reddata + grndata + bludata - clrdata)/2;
  470. if(taos->irdata < 0)
  471. {
  472. taos->irdata=0;
  473. }
  474. #else
  475. taos->irdata = (reddata*IR_R_Coef1 + grndata*IR_G_Coef1 + bludata*IR_B_Coef1 - clrdata*IR_C_Coef1) / IR_Coef1;
  476. #endif
  477. /* remove ir from counts*/
  478. rp1 = taos->reddata - taos->irdata;
  479. gp1 = taos->grndata - taos->irdata;
  480. bp1 = taos->bludata - taos->irdata;
  481. calculated_lux = (rp1 * R_Coef1 + gp1 * G_Coef1 + bp1 * B_Coef1) /1000;
  482. if(calculated_lux < 0)
  483. calculated_lux = 0;
  484. else {
  485. // divide by CPL, CPL = (Atime_ms * ALS_GAIN / DGF);
  486. calculated_lux =calculated_lux*DGF;
  487. calculated_lux *= 10; // Atime_ms
  488. calculated_lux /= Atime_ms;
  489. calculated_lux /= gain;
  490. }
  491. taos->lux = (int)calculated_lux;
  492. return taos->lux;
  493. }
  494. static void taos_light_enable(struct taos_data *taos)
  495. {
  496. taos_dbgmsg("starting poll timer, delay %lldns\n",
  497. ktime_to_ns(taos->light_poll_delay));
  498. taos_get_lux(taos);
  499. hrtimer_start(&taos->timer, taos->light_poll_delay, HRTIMER_MODE_REL);
  500. }
  501. static void taos_light_disable(struct taos_data *taos)
  502. {
  503. taos_dbgmsg("cancelling poll timer\n");
  504. hrtimer_cancel(&taos->timer);
  505. cancel_work_sync(&taos->work_light);
  506. }
  507. static ssize_t poll_delay_show(struct device *dev,
  508. struct device_attribute *attr, char *buf)
  509. {
  510. struct taos_data *taos = dev_get_drvdata(dev);
  511. return sprintf(buf, "%lld\n", ktime_to_ns(taos->light_poll_delay));
  512. }
  513. static ssize_t poll_delay_store(struct device *dev,
  514. struct device_attribute *attr,
  515. const char *buf, size_t size)
  516. {
  517. struct taos_data *taos = dev_get_drvdata(dev);
  518. int64_t new_delay;
  519. int err;
  520. err = strict_strtoll(buf, 10, &new_delay);
  521. if (err < 0)
  522. return err;
  523. taos_dbgmsg("new delay = %lldns, old delay = %lldns\n",
  524. new_delay, ktime_to_ns(taos->light_poll_delay));
  525. mutex_lock(&taos->power_lock);
  526. if (new_delay != ktime_to_ns(taos->light_poll_delay)) {
  527. taos->light_poll_delay = ns_to_ktime(new_delay);
  528. if (taos->power_state & LIGHT_ENABLED) {
  529. taos_light_disable(taos);
  530. taos_light_enable(taos);
  531. }
  532. }
  533. mutex_unlock(&taos->power_lock);
  534. return size;
  535. }
  536. static ssize_t light_enable_show(struct device *dev,
  537. struct device_attribute *attr, char *buf)
  538. {
  539. struct taos_data *taos = dev_get_drvdata(dev);
  540. return sprintf(buf, "%d\n",
  541. (taos->power_state & LIGHT_ENABLED) ? 1 : 0);
  542. }
  543. static ssize_t proximity_enable_show(struct device *dev,
  544. struct device_attribute *attr, char *buf)
  545. {
  546. struct taos_data *taos = dev_get_drvdata(dev);
  547. return sprintf(buf, "%d\n",
  548. (taos->power_state & PROXIMITY_ENABLED) ? 1 : 0);
  549. }
  550. static ssize_t light_enable_store(struct device *dev,
  551. struct device_attribute *attr,
  552. const char *buf, size_t size)
  553. {
  554. struct taos_data *taos = dev_get_drvdata(dev);
  555. bool new_value;
  556. if (sysfs_streq(buf, "1")) {
  557. new_value = true;
  558. } else if (sysfs_streq(buf, "0")) {
  559. new_value = false;
  560. } else {
  561. pr_err("%s: invalid value %d\n", __func__, *buf);
  562. return -EINVAL;
  563. }
  564. mutex_lock(&taos->power_lock);
  565. taos_dbgmsg("new_value = %d, old state = %d\n",
  566. new_value, (taos->power_state & LIGHT_ENABLED) ? 1 : 0);
  567. if (new_value && !(taos->power_state & LIGHT_ENABLED)) {
  568. if (!taos->power_state) {
  569. taos_chip_on(taos);
  570. msleep(60); /*more than 58 ms*/
  571. }
  572. taos->power_state |= LIGHT_ENABLED;
  573. taos_light_enable(taos);
  574. } else if (!new_value && (taos->power_state & LIGHT_ENABLED)) {
  575. taos_light_disable(taos);
  576. taos->power_state &= ~LIGHT_ENABLED;
  577. if (!taos->power_state) {
  578. taos_chip_off(taos);
  579. }
  580. }
  581. mutex_unlock(&taos->power_lock);
  582. return size;
  583. }
  584. static ssize_t proximity_enable_store(struct device *dev,
  585. struct device_attribute *attr,
  586. const char *buf, size_t size)
  587. {
  588. struct taos_data *taos = dev_get_drvdata(dev);
  589. bool new_value;
  590. int temp = 0, ret = 0;
  591. if (sysfs_streq(buf, "1")) {
  592. new_value = true;
  593. } else if (sysfs_streq(buf, "0")) {
  594. new_value = false;
  595. } else {
  596. pr_err("%s: invalid value %d\n", __func__, *buf);
  597. return -EINVAL;
  598. }
  599. mutex_lock(&taos->power_lock);
  600. taos_dbgmsg("new_value = %d, old state = %d\n",
  601. new_value, (taos->power_state & PROXIMITY_ENABLED) ? 1 : 0);
  602. if (new_value && !(taos->power_state & PROXIMITY_ENABLED)) {
  603. if(taos->set_manual_thd == false) {
  604. ret = proximity_open_offset(taos);
  605. if (ret < 0 && ret != -ENOENT)
  606. pr_err("%s: proximity_open_offset() failed\n",
  607. __func__);
  608. #ifdef CONFIG_PROX_WINDOW_TYPE
  609. ret = proximity_open_window_type(taos);
  610. #endif
  611. taos->threshold_high= taos->pdata->prox_thresh_hi + taos->offset_value;
  612. taos->threshold_low = taos->pdata->prox_thresh_low + taos->offset_value;
  613. pr_err("%s: th_hi = %d, th_low = %d\n", __func__,
  614. taos->threshold_high, taos->threshold_low);
  615. }
  616. if (!taos->power_state) {
  617. taos_chip_on(taos);
  618. }
  619. taos->power_state |= PROXIMITY_ENABLED;
  620. taos->proximity_value = STATE_FAR;
  621. taos_thresh_set(taos);
  622. /* interrupt clearing */
  623. temp = (CMD_REG|CMD_SPL_FN|CMD_PROXALS_INTCLR);
  624. ret = opt_i2c_write_command(taos, temp);
  625. if (ret < 0)
  626. gprintk("opt_i2c_write failed, err = %d\n", ret);
  627. #if defined(CONFIG_SEC_S_PROJECT) && defined(CONFIG_INV_MPU_IIO_PRIMARY)
  628. input_report_rel(taos->proximity_input_dev, REL_MISC, 1+1);
  629. #else
  630. input_report_abs(taos->proximity_input_dev, ABS_DISTANCE, 1);
  631. #endif
  632. input_sync(taos->proximity_input_dev);
  633. enable_irq(taos->irq);
  634. enable_irq_wake(taos->irq);
  635. } else if (!new_value && (taos->power_state & PROXIMITY_ENABLED)) {
  636. disable_irq_wake(taos->irq);
  637. disable_irq(taos->irq);
  638. taos->power_state &= ~PROXIMITY_ENABLED;
  639. if (!taos->power_state) {
  640. taos_chip_off(taos);
  641. }
  642. }
  643. mutex_unlock(&taos->power_lock);
  644. return size;
  645. }
  646. static ssize_t proximity_state_show(struct device *dev,
  647. struct device_attribute *attr,
  648. char *buf)
  649. {
  650. struct taos_data *taos = dev_get_drvdata(dev);
  651. int adc = 0;
  652. adc = proximity_get_adc(taos);
  653. return sprintf(buf, "%d\n", adc);
  654. }
  655. #ifdef CONFIG_PROX_WINDOW_TYPE
  656. static void change_proximity_default_threshold(struct taos_data *data)
  657. {
  658. int trim = data->pdata->prox_rawdata_trim;
  659. switch (data->windowtype[1]) {
  660. case WINTYPE_WHITE:
  661. data->pdata->prox_thresh_hi = WHITEWINDOW_HI_THRESHOLD-trim;
  662. data->pdata->prox_thresh_low = WHITEWINDOW_LOW_THRESHOLD-trim;
  663. break;
  664. case WINTYPE_OTHERS:
  665. data->pdata->prox_thresh_hi = BLACKWINDOW_HI_THRESHOLD-trim;
  666. data->pdata->prox_thresh_low = BLACKWINDOW_LOW_THRESHOLD-trim;
  667. break;
  668. default:
  669. data->pdata->prox_thresh_hi = data->pdata->prox_thresh_hi;
  670. data->pdata->prox_thresh_low = data->pdata->prox_thresh_low;
  671. break;
  672. }
  673. }
  674. static int proximity_open_window_type(struct taos_data *data)
  675. {
  676. struct file *wintype_filp = NULL;
  677. int err = 0;
  678. mm_segment_t old_fs;
  679. old_fs = get_fs();
  680. set_fs(KERNEL_DS);
  681. wintype_filp = filp_open(WINDOW_TYPE_FILE_PATH, O_RDONLY, 0666);
  682. if(IS_ERR(wintype_filp)) {
  683. pr_err("%s: no window_type file\n", __func__);
  684. err = PTR_ERR(wintype_filp);
  685. if(err != -ENOENT)
  686. pr_err("%s: Can't open window_type file\n", __func__);
  687. set_fs(old_fs);
  688. data->windowtype[0] = 0;
  689. data->windowtype[1] = 0;
  690. goto exit;
  691. }
  692. err = wintype_filp->f_op->read(wintype_filp,
  693. (u8 *)&data->windowtype, sizeof(u8) * 2, &wintype_filp->f_pos);
  694. if (err != sizeof(u8) * 2) {
  695. pr_err("%s: Can't read the window_type data from file\n", __func__);
  696. err = -EIO;
  697. }
  698. pr_err("%s: %c%c\n",
  699. __func__, data->windowtype[0], data->windowtype[1]);
  700. filp_close(wintype_filp, current->files);
  701. set_fs(old_fs);
  702. exit:
  703. change_proximity_default_threshold(data);
  704. return err;
  705. }
  706. #endif
  707. static int proximity_open_offset(struct taos_data *data)
  708. {
  709. struct file *offset_filp = NULL;
  710. int err = 0;
  711. mm_segment_t old_fs;
  712. old_fs = get_fs();
  713. set_fs(KERNEL_DS);
  714. offset_filp = filp_open(OFFSET_FILE_PATH, O_RDONLY, 0666);
  715. if (IS_ERR(offset_filp)) {
  716. pr_err("%s: no offset file\n", __func__);
  717. err = PTR_ERR(offset_filp);
  718. if (err != -ENOENT)
  719. pr_err("%s: Can't open offset file\n", __func__);
  720. set_fs(old_fs);
  721. return err;
  722. }
  723. err = offset_filp->f_op->read(offset_filp,
  724. (char *)&data->offset_value, sizeof(u16), &offset_filp->f_pos);
  725. if (err != sizeof(u16)) {
  726. pr_err("%s: Can't read the offset data from file\n", __func__);
  727. err = -EIO;
  728. }
  729. pr_err("%s: data->offset_value = %d\n",
  730. __func__, data->offset_value);
  731. filp_close(offset_filp, current->files);
  732. set_fs(old_fs);
  733. return err;
  734. }
  735. static int proximity_adc_read(struct taos_data *taos)
  736. {
  737. int sum[OFFSET_ARRAY_LENGTH];
  738. int i = 0;
  739. int avg = 0;
  740. int min = 0;
  741. int max = 0;
  742. int total = 0;
  743. mutex_lock(&taos->prox_mutex);
  744. for (i = 0; i < OFFSET_ARRAY_LENGTH; i++) {
  745. usleep_range(11000, 11000);
  746. sum[i] = proximity_get_adc(taos);
  747. if (i == 0) {
  748. min = sum[i];
  749. max = sum[i];
  750. } else {
  751. if (sum[i] < min)
  752. min = sum[i];
  753. else if (sum[i] > max)
  754. max = sum[i];
  755. }
  756. total += sum[i];
  757. }
  758. mutex_unlock(&taos->prox_mutex);
  759. total -= (min + max);
  760. avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2));
  761. return avg;
  762. }
  763. static int proximity_store_offset(struct device *dev, bool do_calib)
  764. {
  765. struct taos_data *taos = dev_get_drvdata(dev);
  766. struct file *offset_filp = NULL;
  767. mm_segment_t old_fs;
  768. int err = 0;
  769. u16 abnormal_ct = proximity_adc_read(taos);
  770. u16 offset = 0;
  771. if(do_calib) {
  772. /* tap offset button */
  773. pr_info("[SENSOR] %s: calibration start \n", __func__);
  774. if(abnormal_ct < CAL_SKIP_ADC)
  775. {
  776. taos->offset_value = 0;
  777. taos->threshold_high= taos->pdata->prox_thresh_hi;
  778. taos->threshold_low = taos->pdata->prox_thresh_low;
  779. taos_thresh_set(taos);
  780. taos->set_manual_thd = false;
  781. taos->cal_result = 2;
  782. pr_info("%s: crosstalk < %d, skip calibration\n", __func__, CAL_SKIP_ADC);
  783. }
  784. else if((abnormal_ct >=CAL_SKIP_ADC) && (abnormal_ct <=CAL_FAIL_ADC))
  785. {
  786. offset = abnormal_ct / 2;
  787. taos->offset_value = offset;
  788. taos->threshold_high= taos->pdata->prox_thresh_hi + offset;
  789. taos->threshold_low = taos->pdata->prox_thresh_low+ offset;
  790. taos_thresh_set(taos);
  791. taos->set_manual_thd = false;
  792. taos->cal_result = 1;
  793. }
  794. else
  795. {
  796. taos->offset_value = 0;
  797. taos->threshold_high= taos->pdata->prox_thresh_hi;
  798. taos->threshold_low = taos->pdata->prox_thresh_low;
  799. taos_thresh_set(taos);
  800. taos->set_manual_thd = false;
  801. taos->cal_result = 0;
  802. pr_info("%s: crosstalk > %d, calibration failed \n", __func__, CAL_FAIL_ADC);
  803. }
  804. } else {
  805. /* tap reset button */
  806. pr_info("%s: reset\n", __func__);
  807. taos->threshold_high= taos->pdata->prox_thresh_hi;
  808. taos->threshold_low = taos->pdata->prox_thresh_low;
  809. taos_thresh_set(taos);
  810. taos->offset_value = 0;
  811. taos->cal_result = 2;
  812. taos->set_manual_thd = false;
  813. }
  814. printk("%s: abnormal_ct : %d, offset : %d\n", __func__, abnormal_ct, taos->offset_value);
  815. /* store offset in file */
  816. old_fs = get_fs();
  817. set_fs(KERNEL_DS);
  818. offset_filp = filp_open(OFFSET_FILE_PATH,
  819. O_CREAT | O_TRUNC | O_WRONLY, 0666);
  820. if (IS_ERR(offset_filp)) {
  821. pr_err("%s: Can't open prox_offset file\n", __func__);
  822. set_fs(old_fs);
  823. err = PTR_ERR(offset_filp);
  824. return err;
  825. }
  826. err = offset_filp->f_op->write(offset_filp,
  827. (char *)&taos->offset_value, sizeof(u16), &offset_filp->f_pos);
  828. if (err != sizeof(u16)) {
  829. pr_err("%s: Can't write the offset data to file\n", __func__);
  830. }
  831. filp_close(offset_filp, current->files);
  832. set_fs(old_fs);
  833. return 1;
  834. }
  835. static ssize_t proximity_cal_store(struct device *dev,
  836. struct device_attribute *attr,
  837. const char *buf, size_t size)
  838. {
  839. bool do_calib;
  840. int err;
  841. if (sysfs_streq(buf, "1")) { /* calibrate cancelation value */
  842. do_calib = true;
  843. } else if (sysfs_streq(buf, "0")) { /* reset cancelation value */
  844. do_calib = false;
  845. } else {
  846. pr_err("%s: invalid value %d\n", __func__, *buf);
  847. return -EINVAL;
  848. }
  849. err = proximity_store_offset(dev, do_calib);
  850. if (err < 0) {
  851. pr_err("%s: proximity_store_offset() failed\n", __func__);
  852. return err;
  853. }
  854. return size;
  855. }
  856. static ssize_t proximity_cal_show(struct device *dev,
  857. struct device_attribute *attr, char *buf)
  858. {
  859. struct taos_data *taos = dev_get_drvdata(dev);
  860. proximity_open_offset(taos);
  861. return sprintf(buf, "%d,%d,%d\n",
  862. taos->offset_value, taos->threshold_high, taos->threshold_low);
  863. }
  864. static ssize_t prox_offset_pass_show(struct device *dev,
  865. struct device_attribute *attr, char *buf)
  866. {
  867. struct taos_data *taos = dev_get_drvdata(dev);
  868. return sprintf(buf, "%d\n", taos->cal_result);
  869. }
  870. static ssize_t proximity_avg_show(struct device *dev,
  871. struct device_attribute *attr, char *buf)
  872. {
  873. struct taos_data *taos = dev_get_drvdata(dev);
  874. return sprintf(buf, "%d,%d,%d\n", taos->avg[0], taos->avg[1],
  875. taos->avg[2]);
  876. }
  877. static ssize_t proximity_avg_store(struct device *dev,
  878. struct device_attribute *attr,
  879. const char *buf, size_t size)
  880. {
  881. struct taos_data *taos = dev_get_drvdata(dev);
  882. int new_value = 0;
  883. if (sysfs_streq(buf, "1")) {
  884. new_value = true;
  885. } else if (sysfs_streq(buf, "0")) {
  886. new_value = false;
  887. } else {
  888. pr_err("%s: invalid value %d\n", __func__, *buf);
  889. return -EINVAL;
  890. }
  891. if (taos->prox_avg_enable == new_value)
  892. taos_dbgmsg("%s same status\n", __func__);
  893. else if (new_value == 1) {
  894. taos_dbgmsg("starting poll timer, delay %lldns\n",
  895. ktime_to_ns(taos->prox_polling_time));
  896. hrtimer_start(&taos->prox_avg_timer,
  897. taos->prox_polling_time, HRTIMER_MODE_REL);
  898. taos->prox_avg_enable = 1;
  899. } else {
  900. taos_dbgmsg("cancelling prox avg poll timer\n");
  901. hrtimer_cancel(&taos->prox_avg_timer);
  902. cancel_work_sync(&taos->work_prox_avg);
  903. taos->prox_avg_enable = 0;
  904. }
  905. return 1;
  906. }
  907. static ssize_t proximity_thresh_show(struct device *dev,
  908. struct device_attribute *attr, char *buf)
  909. {
  910. struct taos_data *taos = dev_get_drvdata(dev);
  911. int thresh_hi = 0;
  912. msleep(20);
  913. thresh_hi = taos_proximity_get_threshold(taos, PRX_MAXTHRESHLO);
  914. pr_err("%s: THRESHOLD = %d\n", __func__, thresh_hi);
  915. return sprintf(buf, "prox_threshold = %d\n", thresh_hi);
  916. }
  917. static ssize_t proximity_thresh_store(struct device *dev,
  918. struct device_attribute *attr, const char *buf, size_t size)
  919. {
  920. struct taos_data *taos = dev_get_drvdata(dev);
  921. int thresh_value = (u8)(taos->pdata->prox_thresh_hi);
  922. int err = 0;
  923. err = kstrtoint(buf, 10, &thresh_value);
  924. pr_err( "%s, value = %d\n",__func__,thresh_value);
  925. if (err < 0)
  926. pr_err("%s, kstrtoint failed.", __func__);
  927. taos->threshold_high = thresh_value;
  928. taos_thresh_set(taos);
  929. msleep(20);
  930. return size;
  931. }
  932. static ssize_t thresh_high_show(struct device *dev,
  933. struct device_attribute *attr, char *buf)
  934. {
  935. struct taos_data *taos = dev_get_drvdata(dev);
  936. int thresh_hi = 0,thresh_low = 0;
  937. msleep(20);
  938. thresh_low = taos_proximity_get_threshold(taos, PRX_MINTHRESHLO);
  939. thresh_hi = taos_proximity_get_threshold(taos, PRX_MAXTHRESHLO);
  940. pr_err("%s: thresh_hi = %d, thresh_low = %d\n", __func__, thresh_hi,thresh_low);
  941. return sprintf(buf, "%d,%d\n", thresh_hi,thresh_low);
  942. }
  943. static ssize_t thresh_high_store(struct device *dev,
  944. struct device_attribute *attr, const char *buf, size_t size)
  945. {
  946. struct taos_data *taos = dev_get_drvdata(dev);
  947. int thresh_value = (u8)(taos->pdata->prox_thresh_hi);
  948. int err = 0;
  949. err = kstrtoint(buf, 10, &thresh_value);
  950. printk(KERN_ERR "%s, thresh_value = %d\n",__func__,thresh_value);
  951. if (err < 0)
  952. pr_err("%s, kstrtoint failed.", __func__);
  953. taos->threshold_high = thresh_value;
  954. taos_thresh_set(taos);
  955. msleep(20);
  956. taos->set_manual_thd = true;
  957. return size;
  958. }
  959. static ssize_t thresh_low_show(struct device *dev,
  960. struct device_attribute *attr, char *buf)
  961. {
  962. struct taos_data *taos = dev_get_drvdata(dev);
  963. int thresh_hi = 0,thresh_low = 0;
  964. msleep(20);
  965. thresh_hi = taos_proximity_get_threshold(taos, PRX_MAXTHRESHLO);
  966. thresh_low = taos_proximity_get_threshold(taos, PRX_MINTHRESHLO);
  967. pr_err("%s: thresh_hi = %d, thresh_low = %d\n", __func__, thresh_hi,thresh_low);
  968. return sprintf(buf, "%d,%d\n", thresh_hi,thresh_low);
  969. }
  970. static ssize_t thresh_low_store(struct device *dev,
  971. struct device_attribute *attr, const char *buf, size_t size)
  972. {
  973. struct taos_data *taos = dev_get_drvdata(dev);
  974. int thresh_value = (u8)(taos->pdata->prox_thresh_low);
  975. int err = 0;
  976. err = kstrtoint(buf, 10, &thresh_value);
  977. printk(KERN_ERR "%s, thresh_value = %d\n",__func__,thresh_value);
  978. if (err < 0)
  979. pr_err("%s, kstrtoint failed.", __func__);
  980. taos->threshold_low = thresh_value;
  981. taos_thresh_set(taos);
  982. msleep(20);
  983. taos->set_manual_thd = true;
  984. return size;
  985. }
  986. static ssize_t get_vendor_name(struct device *dev,
  987. struct device_attribute *attr, char *buf)
  988. {
  989. return sprintf(buf, "%s\n", VENDOR_NAME);
  990. }
  991. static ssize_t get_chip_name(struct device *dev,
  992. struct device_attribute *attr, char *buf)
  993. {
  994. return sprintf(buf, "%s\n", CHIP_NAME);
  995. }
  996. static DEVICE_ATTR(vendor, S_IRUGO, get_vendor_name, NULL);
  997. static DEVICE_ATTR(name, S_IRUGO, get_chip_name, NULL);
  998. static ssize_t lightsensor_file_state_show(struct device *dev,
  999. struct device_attribute *attr, char *buf)
  1000. {
  1001. struct taos_data *taos = dev_get_drvdata(dev);
  1002. int adc = 0;
  1003. adc = lightsensor_get_adcvalue(taos);
  1004. return sprintf(buf, "%d\n", adc);
  1005. }
  1006. static ssize_t lightsensor_raw_data_show(struct device *dev,
  1007. struct device_attribute *attr, char *buf)
  1008. {
  1009. struct taos_data *taos = dev_get_drvdata(dev);
  1010. return sprintf(buf, "%u,%u,%u,%u\n",
  1011. taos->reddata, taos->grndata, taos->bludata, taos->clrdata);
  1012. }
  1013. static struct device_attribute dev_attr_light_raw_data =
  1014. __ATTR(raw_data, S_IRUGO, lightsensor_raw_data_show, NULL);
  1015. static DEVICE_ATTR(adc, S_IRUGO, lightsensor_file_state_show, NULL);
  1016. static DEVICE_ATTR(lux, S_IRUGO, lightsensor_file_state_show, NULL);
  1017. static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
  1018. poll_delay_show, poll_delay_store);
  1019. static struct device_attribute dev_attr_light_enable =
  1020. __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
  1021. light_enable_show, light_enable_store);
  1022. static struct attribute *light_sysfs_attrs[] = {
  1023. &dev_attr_light_enable.attr,
  1024. &dev_attr_poll_delay.attr,
  1025. NULL
  1026. };
  1027. static struct attribute_group light_attribute_group = {
  1028. .attrs = light_sysfs_attrs,
  1029. };
  1030. static struct device_attribute *lightsensor_additional_attributes[] = {
  1031. &dev_attr_adc,
  1032. &dev_attr_lux,
  1033. &dev_attr_vendor,
  1034. &dev_attr_name,
  1035. &dev_attr_light_raw_data,
  1036. NULL
  1037. };
  1038. static struct device_attribute dev_attr_proximity_enable =
  1039. __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
  1040. proximity_enable_show, proximity_enable_store);
  1041. static struct attribute *proximity_sysfs_attrs[] = {
  1042. &dev_attr_proximity_enable.attr,
  1043. NULL
  1044. };
  1045. static struct attribute_group proximity_attribute_group = {
  1046. .attrs = proximity_sysfs_attrs,
  1047. };
  1048. static struct device_attribute dev_attr_proximity_raw_data =
  1049. __ATTR(raw_data, S_IRUGO, proximity_state_show, NULL);
  1050. static DEVICE_ATTR(prox_cal, S_IRUGO | S_IWUSR, proximity_cal_show,
  1051. proximity_cal_store);
  1052. static DEVICE_ATTR(prox_avg, S_IRUGO|S_IWUSR, proximity_avg_show,
  1053. proximity_avg_store);
  1054. static DEVICE_ATTR(state, S_IRUGO, proximity_state_show, NULL);
  1055. static DEVICE_ATTR(prox_offset_pass, S_IRUGO,
  1056. prox_offset_pass_show, NULL);
  1057. static DEVICE_ATTR(prox_thresh, 0644, proximity_thresh_show,
  1058. proximity_thresh_store);
  1059. static DEVICE_ATTR(thresh_high, 0644, thresh_high_show,
  1060. thresh_high_store);
  1061. static DEVICE_ATTR(thresh_low, 0644, thresh_low_show,
  1062. thresh_low_store);
  1063. static struct device_attribute *prox_sensor_attrs[] = {
  1064. &dev_attr_state,
  1065. &dev_attr_prox_avg,
  1066. &dev_attr_vendor,
  1067. &dev_attr_name,
  1068. &dev_attr_proximity_raw_data,
  1069. &dev_attr_prox_cal,
  1070. &dev_attr_prox_offset_pass,
  1071. &dev_attr_prox_thresh,
  1072. &dev_attr_thresh_high,
  1073. &dev_attr_thresh_low,
  1074. NULL
  1075. };
  1076. static int lightsensor_get_adcvalue(struct taos_data *taos)
  1077. {
  1078. int i = 0;
  1079. int j = 0;
  1080. unsigned int adc_total = 0;
  1081. int adc_avr_value;
  1082. unsigned int adc_index = 0;
  1083. unsigned int adc_max = 0;
  1084. unsigned int adc_min = 0;
  1085. int value = 0;
  1086. /* get ADC */
  1087. value = taos_get_lux(taos);
  1088. adc_index = (taos->adc_index_count++) % ADC_BUFFER_NUM;
  1089. /*ADC buffer initialize (light sensor off ---> light sensor on) */
  1090. if (!taos->adc_buf_initialized) {
  1091. taos->adc_buf_initialized = true;
  1092. for (j = 0; j < ADC_BUFFER_NUM; j++)
  1093. taos->adc_value_buf[j] = value;
  1094. } else
  1095. taos->adc_value_buf[adc_index] = value;
  1096. adc_max = taos->adc_value_buf[0];
  1097. adc_min = taos->adc_value_buf[0];
  1098. for (i = 0; i < ADC_BUFFER_NUM; i++) {
  1099. adc_total += taos->adc_value_buf[i];
  1100. if (adc_max < taos->adc_value_buf[i])
  1101. adc_max = taos->adc_value_buf[i];
  1102. if (adc_min > taos->adc_value_buf[i])
  1103. adc_min = taos->adc_value_buf[i];
  1104. }
  1105. adc_avr_value = (adc_total-(adc_max+adc_min))/(ADC_BUFFER_NUM - 2);
  1106. if (taos->adc_index_count == ADC_BUFFER_NUM)
  1107. taos->adc_index_count = 0;
  1108. return adc_avr_value;
  1109. }
  1110. static void taos_work_func_light(struct work_struct *work)
  1111. {
  1112. struct taos_data *taos = container_of(work, struct taos_data,
  1113. work_light);
  1114. int adc = taos_get_lux(taos);
  1115. int cct = taos_get_cct(taos);
  1116. input_report_rel(taos->light_input_dev, REL_MISC, adc + 1);
  1117. input_report_rel(taos->light_input_dev, REL_WHEEL, cct);
  1118. input_sync(taos->light_input_dev);
  1119. }
  1120. static void taos_work_func_prox(struct work_struct *work)
  1121. {
  1122. struct taos_data *taos =
  1123. container_of(work, struct taos_data, work_prox);
  1124. int adc_data;
  1125. int threshold_high;
  1126. int threshold_low;
  1127. u8 chipid = 0x69;
  1128. int ret =0;
  1129. int i =0;
  1130. int proximity_value = 0;
  1131. /* disable INT */
  1132. disable_irq_nosync(taos->irq);
  1133. while(chipid != 0x69 && i < 10)
  1134. {
  1135. msleep(5);
  1136. ret = opt_i2c_read(taos, CHIPID, &chipid);
  1137. i++;
  1138. }
  1139. if (ret < 0)
  1140. gprintk("opt_i2c_read failed, err = %d\n", ret);
  1141. /* change Threshold */
  1142. mutex_lock(&taos->prox_mutex);
  1143. adc_data = proximity_get_adc(taos);
  1144. mutex_unlock(&taos->prox_mutex);
  1145. threshold_high = taos_proximity_get_threshold(taos, PRX_MAXTHRESHLO);
  1146. threshold_low = taos_proximity_get_threshold(taos, PRX_MINTHRESHLO);
  1147. pr_err("%s: hi = %d, low = %d, adc_data = %d\n", __func__,
  1148. taos->threshold_high, taos->threshold_low, adc_data);
  1149. if ((threshold_high == (taos->threshold_high)) &&
  1150. (adc_data >= (taos->threshold_high))) {
  1151. proximity_value = STATE_CLOSE;
  1152. #if defined(CONFIG_SEC_S_PROJECT) && defined(CONFIG_INV_MPU_IIO_PRIMARY)
  1153. input_report_rel(taos->proximity_input_dev,
  1154. REL_MISC, proximity_value+1);
  1155. #else
  1156. input_report_abs(taos->proximity_input_dev,
  1157. ABS_DISTANCE, proximity_value);
  1158. #endif
  1159. input_sync(taos->proximity_input_dev);
  1160. pr_info("[%s] prox value = %d\n", __func__, proximity_value);
  1161. } else if ((threshold_high == (0xFFFF)) &&
  1162. (adc_data <= (taos->threshold_low))) {
  1163. proximity_value = STATE_FAR;
  1164. #if defined(CONFIG_SEC_S_PROJECT) && defined(CONFIG_INV_MPU_IIO_PRIMARY)
  1165. input_report_rel(taos->proximity_input_dev,
  1166. REL_MISC, proximity_value+1);
  1167. #else
  1168. input_report_abs(taos->proximity_input_dev,
  1169. ABS_DISTANCE, proximity_value);
  1170. #endif
  1171. input_sync(taos->proximity_input_dev);
  1172. pr_info("[%s] prox value = %d\n", __func__, proximity_value);
  1173. } else {
  1174. pr_err("[%s]Error Case!adc=[%X], th_high=[%d], th_min=[%d]\n",
  1175. __func__, adc_data, threshold_high, threshold_low);
  1176. goto exit;
  1177. }
  1178. taos->proximity_value = proximity_value;
  1179. taos_thresh_set(taos);
  1180. /* reset Interrupt pin */
  1181. /* to active Interrupt, TMD2771x Interuupt pin shoud be reset. */
  1182. exit:
  1183. i2c_smbus_write_byte(taos->i2c_client,
  1184. (CMD_REG|CMD_SPL_FN|CMD_PROXALS_INTCLR));
  1185. /* enable INT */
  1186. enable_irq(taos->irq);
  1187. }
  1188. static void taos_work_func_prox_avg(struct work_struct *work)
  1189. {
  1190. struct taos_data *taos = container_of(work, struct taos_data,
  1191. work_prox_avg);
  1192. int proximity_value = 0;
  1193. int min = 0, max = 0, avg = 0;
  1194. int i = 0;
  1195. for (i = 0; i < PROX_AVG_COUNT; i++) {
  1196. mutex_lock(&taos->prox_mutex);
  1197. proximity_value = proximity_get_adc(taos);
  1198. mutex_unlock(&taos->prox_mutex);
  1199. if (proximity_value > TAOS_PROX_MIN) {
  1200. avg += proximity_value;
  1201. if (!i)
  1202. min = proximity_value;
  1203. if (proximity_value < min)
  1204. min = proximity_value;
  1205. if (proximity_value > max)
  1206. max = proximity_value;
  1207. } else {
  1208. proximity_value = TAOS_PROX_MIN;
  1209. }
  1210. msleep(40);
  1211. }
  1212. avg /= i;
  1213. taos->avg[0] = min;
  1214. taos->avg[1] = avg;
  1215. taos->avg[2] = max;
  1216. }
  1217. /* This function is for light sensor. It operates every a few seconds.
  1218. * It asks for work to be done on a thread because i2c needs a thread
  1219. * context (slow and blocking) and then reschedules the timer to run again.
  1220. */
  1221. static enum hrtimer_restart taos_timer_func(struct hrtimer *timer)
  1222. {
  1223. struct taos_data *taos = container_of(timer, struct taos_data, timer);
  1224. queue_work(taos->wq, &taos->work_light);
  1225. hrtimer_forward_now(&taos->timer, taos->light_poll_delay);
  1226. return HRTIMER_RESTART;
  1227. }
  1228. static enum hrtimer_restart taos_prox_timer_func(struct hrtimer *timer)
  1229. {
  1230. struct taos_data *taos = container_of(timer, struct taos_data,
  1231. prox_avg_timer);
  1232. queue_work(taos->wq_avg, &taos->work_prox_avg);
  1233. hrtimer_forward_now(&taos->prox_avg_timer, taos->prox_polling_time);
  1234. return HRTIMER_RESTART;
  1235. }
  1236. /* interrupt happened due to transition/change of near/far proximity state */
  1237. irqreturn_t taos_irq_handler(int irq, void *data)
  1238. {
  1239. struct taos_data *ip = data;
  1240. if (ip->irq != -1) {
  1241. wake_lock_timeout(&ip->prx_wake_lock, 3*HZ);
  1242. queue_work(ip->wq, &ip->work_prox);
  1243. }
  1244. pr_err("taos interrupt handler is called\n");
  1245. return IRQ_HANDLED;
  1246. }
  1247. static int taos_setup_irq(struct taos_data *taos)
  1248. {
  1249. int rc = -EIO;
  1250. struct taos_platform_data *pdata = taos->pdata;
  1251. int irq;
  1252. taos_dbgmsg("start\n");
  1253. rc = gpio_request(pdata->als_int, "gpio_proximity_out");
  1254. if (rc < 0) {
  1255. pr_err("%s: gpio %d request failed (%d)\n",
  1256. __func__, pdata->als_int, rc);
  1257. return rc;
  1258. }
  1259. rc = gpio_direction_input(pdata->als_int);
  1260. if (rc < 0) {
  1261. pr_err("%s: failed to set gpio %d as input (%d)\n",
  1262. __func__, pdata->als_int, rc);
  1263. goto err_gpio_direction_input;
  1264. }
  1265. irq = gpio_to_irq(pdata->als_int);
  1266. rc = request_threaded_irq(irq, NULL,
  1267. taos_irq_handler,
  1268. IRQF_TRIGGER_FALLING,
  1269. "proximity_int",
  1270. taos);
  1271. if (rc < 0) {
  1272. pr_err("%s: request_irq(%d) failed for gpio %d (%d)\n",
  1273. __func__, irq,
  1274. pdata->als_int, rc);
  1275. goto err_request_irq;
  1276. }
  1277. /* start with interrupts disabled */
  1278. disable_irq(irq);
  1279. taos->irq = irq;
  1280. taos_dbgmsg("success\n");
  1281. goto done;
  1282. err_request_irq:
  1283. err_gpio_direction_input:
  1284. gpio_free(pdata->als_int);
  1285. done:
  1286. return rc;
  1287. }
  1288. static int taos_get_initial_offset(struct taos_data *taos)
  1289. {
  1290. int ret = 0;
  1291. u8 p_offset = 0;
  1292. ret = proximity_open_offset(taos);
  1293. if(ret < 0) {
  1294. p_offset = 0;
  1295. taos->offset_value = 0;
  1296. } else
  1297. p_offset = taos->offset_value;
  1298. pr_err("%s: initial offset = %d\n", __func__, p_offset);
  1299. return p_offset;
  1300. }
  1301. #ifdef CONFIG_OF
  1302. /* device tree parsing function */
  1303. static int taos_parse_dt(struct device *dev,
  1304. struct taos_platform_data *pdata)
  1305. {
  1306. struct device_node *np = dev->of_node;
  1307. pdata->als_int = of_get_named_gpio_flags(np, "taos,irq_gpio",
  1308. 0, &pdata->als_int_flags);
  1309. #if defined(CONFIG_SEC_S_PROJECT)
  1310. pdata->enable = of_get_named_gpio(np, "taos,en", 0);
  1311. #endif
  1312. #ifdef CONFIG_SEC_RUBENS_PROJECT
  1313. //set trim
  1314. pdata->prox_rawdata_trim=130;
  1315. // set threshold - prox_rawdata_trim value
  1316. pdata->prox_thresh_hi = 480,
  1317. pdata->prox_thresh_low = 340,
  1318. pdata->prox_pulsecnt = 0x06,
  1319. #else
  1320. pdata->prox_rawdata_trim=150;
  1321. pdata->prox_thresh_hi = 650,
  1322. pdata->prox_thresh_low = 470,
  1323. pdata->prox_pulsecnt = 0x08,
  1324. #endif
  1325. pdata->prox_th_hi_cal = 380,
  1326. pdata->prox_th_low_cal = 250,
  1327. //set offset- prox_rawdata_trim value
  1328. pdata->crosstalk_max_offset = 350,
  1329. pdata->thresholed_max_offset = 750,
  1330. pdata->als_time = 0xEB,
  1331. pdata->intr_filter = 0x33,
  1332. pdata->als_gain = 0x22,
  1333. pdata->coef_atime = 50,
  1334. pdata->ga = 97,
  1335. pdata->coef_a = 1000,
  1336. pdata->coef_b = 1880,
  1337. pdata->coef_c = 642,
  1338. pdata->coef_d = 1140,
  1339. #if defined(CONFIG_SEC_S_PROJECT)
  1340. printk(KERN_INFO "%s irq_gpio:%d and enable gpio %d \n", __func__, pdata->als_int, pdata->enable);
  1341. #else
  1342. printk(KERN_INFO "%s irq_gpio:%d\n", __func__, pdata->als_int);
  1343. #endif
  1344. return 0;
  1345. }
  1346. #else
  1347. static int taos_parse_dt(struct device *dev,
  1348. struct taos_platform_data)
  1349. {
  1350. return -ENODEV;
  1351. }
  1352. #endif
  1353. static int taos_i2c_probe(struct i2c_client *client,
  1354. const struct i2c_device_id *id)
  1355. {
  1356. int ret = -ENODEV,err;
  1357. int chipid = 0;
  1358. struct input_dev *input_dev;
  1359. struct taos_data *taos;
  1360. struct taos_platform_data *pdata = NULL;
  1361. printk("taos_i2c_probe Start\n");
  1362. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  1363. pr_err("%s: i2c functionality check failed!\n", __func__);
  1364. return ret;
  1365. }
  1366. taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL);
  1367. if (!taos) {
  1368. pr_err("%s: failed to alloc memory for module data\n",
  1369. __func__);
  1370. ret = -ENOMEM;
  1371. goto done;
  1372. }
  1373. if(client->dev.of_node) {
  1374. pdata = devm_kzalloc (&client->dev ,
  1375. sizeof(struct taos_platform_data ), GFP_KERNEL);
  1376. if(!pdata) {
  1377. dev_err(&client->dev, "Failed to allocate memory\n");
  1378. ret = -ENOMEM;
  1379. goto err_taos_data_free;
  1380. }
  1381. err = taos_parse_dt(&client->dev, pdata);
  1382. if(err)
  1383. goto err_devicetree;
  1384. } else
  1385. pdata = client->dev.platform_data;
  1386. if (!pdata) {
  1387. pr_err("%s: missing pdata!\n", __func__);
  1388. goto err_taos_data_free;
  1389. }
  1390. taos->pdata = pdata;
  1391. taos->i2c_client = client;
  1392. i2c_set_clientdata(client, taos);
  1393. taos->lux = 0;
  1394. taos->offset_value = taos_get_initial_offset(taos);
  1395. #ifdef CONFIG_PROX_WINDOW_TYPE
  1396. proximity_open_window_type(taos);
  1397. #endif
  1398. taos->set_manual_thd = false;
  1399. sensor_power_on_vdd(taos,1);
  1400. /* ID Check */
  1401. chipid = i2c_smbus_read_byte_data(client, CMD_REG | CHIPID);
  1402. if (chipid != CHIP_ID) {
  1403. pr_err("%s: i2c read error [%X]\n", __func__, chipid);
  1404. goto err_chip_id_or_i2c_error;
  1405. }
  1406. taos->threshold_high = taos->pdata->prox_thresh_hi + taos->offset_value;
  1407. taos->threshold_low = taos->pdata->prox_thresh_low + taos->offset_value;
  1408. mutex_init(&taos->prox_mutex);
  1409. /* wake lock init */
  1410. wake_lock_init(&taos->prx_wake_lock, WAKE_LOCK_SUSPEND,
  1411. "prx_wake_lock");
  1412. mutex_init(&taos->power_lock);
  1413. /* allocate proximity input_device */
  1414. input_dev = input_allocate_device();
  1415. if (!input_dev) {
  1416. pr_err("%s: could not allocate input device\n", __func__);
  1417. goto err_input_allocate_device_proximity;
  1418. }
  1419. taos->proximity_input_dev = input_dev;
  1420. input_set_drvdata(input_dev, taos);
  1421. input_dev->name = "proximity_sensor";
  1422. #if defined(CONFIG_SEC_S_PROJECT) && defined(CONFIG_INV_MPU_IIO_PRIMARY)
  1423. input_set_capability(input_dev, EV_REL, REL_MISC);
  1424. #else
  1425. input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
  1426. #endif
  1427. input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
  1428. taos_dbgmsg("registering proximity input device\n");
  1429. ret = input_register_device(input_dev);
  1430. if (ret < 0) {
  1431. pr_err("%s: could not register input device\n", __func__);
  1432. input_free_device(input_dev);
  1433. goto err_input_register_device_proximity;
  1434. }
  1435. ret=sensors_register(taos->proximity_dev, taos, prox_sensor_attrs,MODULE_NAME_PROX); //factory attributs
  1436. if (ret < 0) {
  1437. pr_err("%s: could not registersensors_register\n", __func__);
  1438. input_unregister_device(input_dev);
  1439. goto err_input_register_device_proximity;
  1440. }
  1441. ret = sensors_create_symlink(&input_dev->dev.kobj, input_dev->name);
  1442. if (ret < 0) {
  1443. input_unregister_device(input_dev);
  1444. sensors_unregister(taos->proximity_dev, prox_sensor_attrs);
  1445. goto err_input_register_device_proximity;
  1446. }
  1447. ret = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group);
  1448. if (ret < 0) {
  1449. pr_err("%s: could not create sysfs group\n", __func__);
  1450. input_unregister_device(input_dev);
  1451. sensors_unregister(taos->proximity_dev, prox_sensor_attrs);
  1452. sensors_remove_symlink(&input_dev->dev.kobj,taos->proximity_input_dev->name);
  1453. goto err_input_register_device_proximity;
  1454. }
  1455. /* hrtimer settings. we poll for light values using a timer. */
  1456. hrtimer_init(&taos->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  1457. taos->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
  1458. taos->timer.function = taos_timer_func;
  1459. /* the timer just fires off a work queue request. we need a thread
  1460. to read the i2c (can be slow and blocking). */
  1461. taos->wq = create_singlethread_workqueue("taos_wq");
  1462. if (!taos->wq) {
  1463. ret = -ENOMEM;
  1464. pr_err("%s: could not create workqueue\n", __func__);
  1465. goto err_create_workqueue;
  1466. }
  1467. taos->wq_avg = create_singlethread_workqueue("taos_wq_avg");
  1468. if (!taos->wq_avg) {
  1469. ret = -ENOMEM;
  1470. pr_err("%s: could not create workqueue\n", __func__);
  1471. goto err_create_avg_workqueue;
  1472. }
  1473. /* this is the thread function we run on the work queue */
  1474. INIT_WORK(&taos->work_light, taos_work_func_light);
  1475. INIT_WORK(&taos->work_prox, taos_work_func_prox);
  1476. INIT_WORK(&taos->work_prox_avg, taos_work_func_prox_avg);
  1477. taos->prox_avg_enable = 0;
  1478. hrtimer_init(&taos->prox_avg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  1479. taos->prox_polling_time = ns_to_ktime(2000 * NSEC_PER_MSEC);
  1480. taos->prox_avg_timer.function = taos_prox_timer_func;
  1481. /* allocate lightsensor-level input_device */
  1482. input_dev = input_allocate_device();
  1483. if (!input_dev) {
  1484. pr_err("%s: could not allocate input device\n", __func__);
  1485. ret = -ENOMEM;
  1486. goto err_input_allocate_device_light;
  1487. }
  1488. input_set_drvdata(input_dev, taos);
  1489. input_dev->name = "light_sensor";
  1490. input_set_capability(input_dev, EV_REL, REL_MISC);
  1491. input_set_capability(input_dev, EV_REL, REL_WHEEL);
  1492. taos_dbgmsg("registering lightsensor-level input device\n");
  1493. ret = input_register_device(input_dev);
  1494. if (ret < 0) {
  1495. pr_err("%s: could not register input device\n", __func__);
  1496. input_free_device(input_dev);
  1497. goto err_input_register_device_light;
  1498. }
  1499. ret = sensors_register(taos->light_dev,taos, lightsensor_additional_attributes,"light_sensor");
  1500. if (ret < 0) {
  1501. pr_err("%s: cound not register light sensor device(%d).\n",
  1502. __func__, ret);
  1503. input_unregister_device(input_dev);
  1504. goto err_input_register_device_light;
  1505. }
  1506. ret = sensors_create_symlink(&input_dev->dev.kobj, input_dev->name);
  1507. if (ret < 0) {
  1508. input_unregister_device(input_dev);
  1509. sensors_unregister(taos->light_dev, lightsensor_additional_attributes);
  1510. goto out_sensor_register_failed1;
  1511. }
  1512. ret = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group);
  1513. if (ret < 0) {
  1514. pr_err("%s: could not create sysfs group\n", __func__);
  1515. input_unregister_device(input_dev);
  1516. sensors_unregister(taos->light_dev, lightsensor_additional_attributes);
  1517. sensors_remove_symlink(&taos->light_input_dev->dev.kobj,taos->proximity_input_dev->name);
  1518. goto out_sensor_register_failed1;
  1519. }
  1520. taos->light_input_dev = input_dev;
  1521. ret = taos_setup_irq(taos);
  1522. if (ret < 0) {
  1523. pr_err("%s: could not setup irq\n", __func__);
  1524. goto err_setup_irq;
  1525. }
  1526. #ifndef CONFIG_SEC_RUBENS_PROJECT
  1527. sensor_power_on_vdd(taos,0);
  1528. #endif
  1529. goto done;
  1530. /* error, unwind it all */
  1531. err_devicetree:
  1532. printk("\n error in device tree");
  1533. out_sensor_register_failed1:
  1534. sensors_unregister(taos->light_dev, lightsensor_additional_attributes);
  1535. err_setup_irq:
  1536. err_input_register_device_light:
  1537. err_input_allocate_device_light:
  1538. destroy_workqueue(taos->wq_avg);
  1539. err_create_avg_workqueue:
  1540. destroy_workqueue(taos->wq);
  1541. err_create_workqueue:
  1542. sysfs_remove_group(&taos->proximity_input_dev->dev.kobj,
  1543. &proximity_attribute_group);
  1544. err_input_register_device_proximity:
  1545. err_input_allocate_device_proximity:
  1546. free_irq(taos->irq, 0);
  1547. gpio_free(taos->pdata->als_int);
  1548. mutex_destroy(&taos->power_lock);
  1549. wake_lock_destroy(&taos->prx_wake_lock);
  1550. err_taos_data_free:
  1551. err_chip_id_or_i2c_error:
  1552. kfree(taos);
  1553. done:
  1554. return ret;
  1555. }
  1556. static int taos_suspend(struct device *dev)
  1557. {
  1558. /* We disable power only if proximity is disabled. If proximity
  1559. is enabled, we leave power on because proximity is allowed
  1560. to wake up device. We remove power without changing
  1561. taos->power_state because we use that state in resume.
  1562. */
  1563. struct i2c_client *client = to_i2c_client(dev);
  1564. struct taos_data *taos = i2c_get_clientdata(client);
  1565. if (taos->power_state & LIGHT_ENABLED){
  1566. taos_light_disable(taos);
  1567. }
  1568. if (taos->power_state == LIGHT_ENABLED) {
  1569. taos_chip_off(taos);
  1570. }
  1571. return 0;
  1572. }
  1573. static int taos_resume(struct device *dev)
  1574. {
  1575. /* Turn power back on if we were before suspend. */
  1576. struct i2c_client *client = to_i2c_client(dev);
  1577. struct taos_data *taos = i2c_get_clientdata(client);
  1578. if (taos->power_state == LIGHT_ENABLED) {
  1579. taos_chip_on(taos);
  1580. }
  1581. if (taos->power_state & LIGHT_ENABLED){
  1582. taos_light_enable(taos);
  1583. }
  1584. return 0;
  1585. }
  1586. static int taos_i2c_remove(struct i2c_client *client)
  1587. {
  1588. struct taos_data *taos = i2c_get_clientdata(client);
  1589. sensors_unregister(taos->proximity_dev, prox_sensor_attrs);
  1590. sensors_remove_symlink(&taos->proximity_input_dev->dev.kobj,taos->proximity_input_dev->name);
  1591. sysfs_remove_group(&taos->proximity_input_dev->dev.kobj, &proximity_attribute_group);
  1592. input_unregister_device(taos->light_input_dev);
  1593. sensors_unregister(taos->light_dev, lightsensor_additional_attributes);
  1594. sensors_remove_symlink(&taos->light_input_dev->dev.kobj,taos->proximity_input_dev->name);
  1595. sysfs_remove_group(&taos->light_input_dev->dev.kobj, &light_attribute_group);
  1596. input_unregister_device(taos->proximity_input_dev);
  1597. free_irq(taos->irq, NULL);
  1598. gpio_free(taos->pdata->als_int);
  1599. if (taos->power_state) {
  1600. taos->power_state = 0;
  1601. if (taos->power_state & LIGHT_ENABLED)
  1602. taos_light_disable(taos);
  1603. taos->pdata->power(false);
  1604. sensor_power_on_vdd(taos,0);
  1605. }
  1606. destroy_workqueue(taos->wq);
  1607. destroy_workqueue(taos->wq_avg);
  1608. mutex_destroy(&taos->power_lock);
  1609. wake_lock_destroy(&taos->prx_wake_lock);
  1610. kfree(taos);
  1611. return 0;
  1612. }
  1613. static const struct i2c_device_id taos_device_id[] = {
  1614. {"taos", 0},
  1615. {}
  1616. };
  1617. MODULE_DEVICE_TABLE(i2c, taos_device_id);
  1618. static const struct dev_pm_ops taos_pm_ops = {
  1619. .suspend = taos_suspend,
  1620. .resume = taos_resume
  1621. };
  1622. #ifdef CONFIG_OF
  1623. static struct of_device_id tm3782_match_table[] = {
  1624. { .compatible = "taos,tmd3782",},
  1625. {},
  1626. };
  1627. #else
  1628. #define tm2672_match_table NULL
  1629. #endif
  1630. static struct i2c_driver taos_i2c_driver = {
  1631. .driver = {
  1632. .name = "taos",
  1633. .owner = THIS_MODULE,
  1634. .pm = &taos_pm_ops,
  1635. .of_match_table = tm3782_match_table,
  1636. },
  1637. .probe = taos_i2c_probe,
  1638. .remove = taos_i2c_remove,
  1639. .id_table = taos_device_id,
  1640. };
  1641. static int __init taos_init(void)
  1642. {
  1643. return i2c_add_driver(&taos_i2c_driver);
  1644. }
  1645. static void __exit taos_exit(void)
  1646. {
  1647. i2c_del_driver(&taos_i2c_driver);
  1648. }
  1649. module_init(taos_init);
  1650. module_exit(taos_exit);
  1651. MODULE_AUTHOR("SAMSUNG");
  1652. MODULE_DESCRIPTION("Optical Sensor driver for taos");
  1653. MODULE_LICENSE("GPL");