APDS9930.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173
  1. /* drivers/hwmon/mt6516/amit/APDS9930.c - APDS9930 ALS/PS driver
  2. *
  3. * Author: MingHsien Hsieh <minghsien.hsieh@mediatek.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. */
  15. #include <alsps.h>
  16. #include <hwmsensor.h>
  17. #include <cust_alsps.h>
  18. #include "APDS9930.h"
  19. #include <linux/gpio.h>
  20. #include <linux/of.h>
  21. #include <linux/of_address.h>
  22. #include <linux/of_device.h>
  23. #include <linux/of_gpio.h>
  24. #include <linux/of_irq.h>
  25. /******************************************************************************
  26. * configuration
  27. *******************************************************************************/
  28. /*----------------------------------------------------------------------------*/
  29. #define APDS9930_DEV_NAME "APDS9930"
  30. /*----------------------------------------------------------------------------*/
  31. #define APS_TAG "[ALS/PS] "
  32. #define APS_FUN(f) pr_debug(APS_TAG"%s\n", __func__)
  33. #define APS_ERR(fmt, args...) pr_err(APS_TAG"%s %d : "fmt, __func__, __LINE__, ##args)
  34. #define APS_LOG(fmt, args...) pr_debug(APS_TAG fmt, ##args)
  35. #define APS_DBG(fmt, args...) pr_debug(APS_TAG fmt, ##args)
  36. #define I2C_FLAG_WRITE 0
  37. #define I2C_FLAG_READ 1
  38. int APDS9930_CMM_PPCOUNT_VALUE = 0x08;
  39. int APDS9930_CMM_CONTROL_VALUE = 0xE4;
  40. int ZOOM_TIME = 4;
  41. /*unsigned int alsps_int_gpio_number = 0;
  42. static int of_get_APDS9930_platform_data(struct device *dev);*/
  43. struct alsps_hw alsps_cust;
  44. static struct alsps_hw *hw = &alsps_cust;
  45. struct platform_device *alspsPltFmDev;
  46. /* For alsp driver get cust info */
  47. struct alsps_hw *get_cust_alsps(void)
  48. {
  49. return &alsps_cust;
  50. }
  51. /*----------------------------------------------------------------------------*/
  52. static struct i2c_client *APDS9930_i2c_client;
  53. /*----------------------------------------------------------------------------*/
  54. static const struct i2c_device_id APDS9930_i2c_id[] = { {APDS9930_DEV_NAME, 0}, {} };
  55. /*----------------------------------------------------------------------------*/
  56. static int APDS9930_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
  57. static int APDS9930_i2c_remove(struct i2c_client *client);
  58. static int APDS9930_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
  59. /*----------------------------------------------------------------------------*/
  60. static int APDS9930_i2c_suspend(struct i2c_client *client, pm_message_t msg);
  61. static int APDS9930_i2c_resume(struct i2c_client *client);
  62. static int APDS9930_remove(void);
  63. static int APDS9930_local_init(void);
  64. static int APDS9930_init_flag = -1; /* 0<==>OK -1 <==> fail*/
  65. static struct alsps_init_info APDS9930_init_info = {
  66. .name = "APDS9930",
  67. .init = APDS9930_local_init,
  68. .uninit = APDS9930_remove,
  69. };
  70. static DEFINE_MUTEX(APDS9930_mutex);
  71. static struct APDS9930_priv *g_APDS9930_ptr;
  72. static unsigned int alsps_irq;
  73. struct PS_CALI_DATA_STRUCT {
  74. int close;
  75. int far_away;
  76. int valid;
  77. };
  78. static struct PS_CALI_DATA_STRUCT ps_cali = { 0, 0, 0 };
  79. static int intr_flag_value;
  80. static unsigned long long int_top_time;
  81. enum {
  82. CMC_BIT_ALS = 1,
  83. CMC_BIT_PS = 2,
  84. };
  85. /*----------------------------------------------------------------------------*/
  86. struct APDS9930_i2c_addr { /*define a series of i2c slave address */
  87. u8 write_addr;
  88. u8 ps_thd; /*PS INT threshold */
  89. };
  90. /*----------------------------------------------------------------------------*/
  91. struct APDS9930_priv {
  92. struct alsps_hw *hw;
  93. struct i2c_client *client;
  94. struct work_struct irq_work;
  95. struct device_node *irq_node;
  96. /*i2c address group */
  97. struct APDS9930_i2c_addr addr;
  98. /*misc */
  99. u16 als_modulus;
  100. atomic_t i2c_retry;
  101. atomic_t als_suspend;
  102. atomic_t als_debounce; /*debounce time after enabling als */
  103. atomic_t als_deb_on; /*indicates if the debounce is on */
  104. atomic_t als_deb_end; /*the jiffies representing the end of debounce */
  105. atomic_t ps_mask; /*mask ps: always return far away */
  106. atomic_t ps_debounce; /*debounce time after enabling ps */
  107. atomic_t ps_deb_on; /*indicates if the debounce is on */
  108. atomic_t ps_deb_end; /*the jiffies representing the end of debounce */
  109. atomic_t ps_suspend;
  110. /*data */
  111. u16 als;
  112. u16 ps;
  113. u8 _align;
  114. u16 als_level_num;
  115. u16 als_value_num;
  116. u32 als_level[C_CUST_ALS_LEVEL - 1];
  117. u32 als_value[C_CUST_ALS_LEVEL];
  118. int ps_cali;
  119. atomic_t als_cmd_val; /*the cmd value can't be read, stored in ram */
  120. atomic_t ps_cmd_val; /*the cmd value can't be read, stored in ram */
  121. atomic_t ps_thd_val_high; /*the cmd value can't be read, stored in ram */
  122. atomic_t ps_thd_val_low; /*the cmd value can't be read, stored in ram */
  123. ulong enable; /*enable mask */
  124. ulong pending_intr; /*pending interrupt */
  125. /*early suspend */
  126. #if defined(CONFIG_HAS_EARLYSUSPEND)
  127. struct early_suspend early_drv;
  128. #endif
  129. };
  130. #ifdef CONFIG_OF
  131. static const struct of_device_id alsps_of_match[] = {
  132. {.compatible = "mediatek,alsps"},
  133. {},
  134. };
  135. #endif
  136. /*----------------------------------------------------------------------------*/
  137. static struct i2c_driver APDS9930_i2c_driver = {
  138. .probe = APDS9930_i2c_probe,
  139. .remove = APDS9930_i2c_remove,
  140. .detect = APDS9930_i2c_detect,
  141. .suspend = APDS9930_i2c_suspend,
  142. .resume = APDS9930_i2c_resume,
  143. .id_table = APDS9930_i2c_id,
  144. .driver = {
  145. .name = APDS9930_DEV_NAME,
  146. #ifdef CONFIG_OF
  147. .of_match_table = alsps_of_match,
  148. #endif
  149. },
  150. };
  151. static struct APDS9930_priv *APDS9930_obj;
  152. /*------------------------i2c function for 89-------------------------------------*/
  153. int APDS9930_i2c_master_operate(struct i2c_client *client, char *buf, int count, int i2c_flag)
  154. {
  155. int res = 0;
  156. mutex_lock(&APDS9930_mutex);
  157. switch (i2c_flag) {
  158. case I2C_FLAG_WRITE:
  159. /* client->addr &= I2C_MASK_FLAG; */
  160. res = i2c_master_send(client, buf, count);
  161. /* client->addr &= I2C_MASK_FLAG; */
  162. break;
  163. case I2C_FLAG_READ:
  164. /*
  165. client->addr &= I2C_MASK_FLAG;
  166. client->addr |= I2C_WR_FLAG;
  167. client->addr |= I2C_RS_FLAG;
  168. */
  169. res = i2c_master_send(client, buf, count & 0xFF);
  170. /* client->addr &= I2C_MASK_FLAG; */
  171. res = i2c_master_recv(client, buf, count >> 0x08);
  172. break;
  173. default:
  174. APS_LOG("APDS9930_i2c_master_operate i2c_flag command not support!\n");
  175. break;
  176. }
  177. if (res <= 0)
  178. goto EXIT_ERR;
  179. mutex_unlock(&APDS9930_mutex);
  180. return res;
  181. EXIT_ERR:
  182. mutex_unlock(&APDS9930_mutex);
  183. APS_ERR("APDS9930_i2c_transfer fail\n");
  184. return res;
  185. }
  186. /*----------------------------------------------------------------------------*/
  187. int APDS9930_get_addr(struct alsps_hw *hw, struct APDS9930_i2c_addr *addr)
  188. {
  189. if (!hw || !addr)
  190. return -EFAULT;
  191. addr->write_addr = hw->i2c_addr[0];
  192. return 0;
  193. }
  194. /*----------------------------------------------------------------------------*/
  195. static void APDS9930_power(struct alsps_hw *hw, unsigned int on)
  196. {
  197. }
  198. /*----------------------------------------------------------------------------*/
  199. static long APDS9930_enable_als(struct i2c_client *client, int enable)
  200. {
  201. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  202. u8 databuf[2];
  203. long res = 0;
  204. databuf[0] = APDS9930_CMM_ENABLE;
  205. res = APDS9930_i2c_master_operate(client, databuf, 0x101, I2C_FLAG_READ);
  206. if (res <= 0)
  207. goto EXIT_ERR;
  208. /* APS_LOG("APDS9930_CMM_ENABLE als value = %x\n",databuf[0]); */
  209. if (enable) {
  210. databuf[1] = databuf[0] | 0x03;
  211. databuf[0] = APDS9930_CMM_ENABLE;
  212. /* APS_LOG("APDS9930_CMM_ENABLE enable als value = %x\n",databuf[1]); */
  213. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  214. if (res <= 0)
  215. goto EXIT_ERR;
  216. atomic_set(&obj->als_deb_on, 1);
  217. atomic_set(&obj->als_deb_end,
  218. jiffies + atomic_read(&obj->als_debounce) / (1000 / HZ));
  219. } else {
  220. if (test_bit(CMC_BIT_PS, &obj->enable))
  221. databuf[1] = databuf[0] & 0xFD;
  222. else
  223. databuf[1] = databuf[0] & 0xF8;
  224. databuf[0] = APDS9930_CMM_ENABLE;
  225. /* APS_LOG("APDS9930_CMM_ENABLE disable als value = %x\n",databuf[1]); */
  226. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  227. if (res <= 0)
  228. goto EXIT_ERR;
  229. }
  230. return 0;
  231. EXIT_ERR:
  232. APS_ERR("APDS9930_enable_als fail\n");
  233. return res;
  234. }
  235. /*----------------------------------------------------------------------------*/
  236. static long APDS9930_enable_ps(struct i2c_client *client, int enable)
  237. {
  238. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  239. u8 databuf[2];
  240. long res = 0;
  241. databuf[0] = APDS9930_CMM_ENABLE;
  242. res = APDS9930_i2c_master_operate(client, databuf, 0x101, I2C_FLAG_READ);
  243. if (res <= 0)
  244. goto EXIT_ERR;
  245. /* APS_LOG("APDS9930_CMM_ENABLE ps value = %x\n",databuf[0]); */
  246. if (enable) {
  247. databuf[1] = databuf[0] | 0x05;
  248. databuf[0] = APDS9930_CMM_ENABLE;
  249. /* APS_LOG("APDS9930_CMM_ENABLE enable ps value = %x\n",databuf[1]); */
  250. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  251. if (res <= 0)
  252. goto EXIT_ERR;
  253. atomic_set(&obj->ps_deb_on, 1);
  254. atomic_set(&obj->ps_deb_end,
  255. jiffies + atomic_read(&obj->ps_debounce) / (1000 / HZ));
  256. } else {
  257. if (test_bit(CMC_BIT_ALS, &obj->enable))
  258. databuf[1] = databuf[0] & 0xFB;
  259. else
  260. databuf[1] = databuf[0] & 0xF8;
  261. databuf[0] = APDS9930_CMM_ENABLE;
  262. /* APS_LOG("APDS9930_CMM_ENABLE disable ps value = %x\n",databuf[1]); */
  263. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  264. if (res <= 0)
  265. goto EXIT_ERR;
  266. /*fix bug */
  267. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  268. databuf[1] = (u8)(750 & 0x00FF);
  269. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  270. if (res <= 0)
  271. goto EXIT_ERR;
  272. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  273. databuf[1] = (u8)((750 & 0xFF00) >> 8);
  274. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  275. if (res <= 0)
  276. goto EXIT_ERR;
  277. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  278. databuf[1] = (u8)(900 & 0x00FF);
  279. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  280. if (res <= 0)
  281. goto EXIT_ERR;
  282. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  283. databuf[1] = (u8)((900 & 0xFF00) >> 8);
  284. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  285. if (res <= 0)
  286. goto EXIT_ERR;
  287. /*fix bug */
  288. }
  289. return 0;
  290. EXIT_ERR:
  291. APS_ERR("APDS9930_enable_ps fail\n");
  292. return res;
  293. }
  294. /*----------------------------------------------------------------------------*/
  295. /*for interrupt work mode support -- by liaoxl.lenovo 12.08.2011*/
  296. static int APDS9930_check_and_clear_intr(struct i2c_client *client)
  297. {
  298. int res, intp, intl;
  299. u8 buffer[2];
  300. /* gpio_direction_input(alsps_int_gpio_number);
  301. if (gpio_get_value(alsps_int_gpio_number) == 1)//skip if no interrupt
  302. return 0;
  303. */
  304. buffer[0] = APDS9930_CMM_STATUS;
  305. res = APDS9930_i2c_master_operate(client, buffer, 0x101, I2C_FLAG_READ);
  306. if (res <= 0)
  307. goto EXIT_ERR;
  308. res = 0;
  309. intp = 0;
  310. intl = 0;
  311. if (0 != (buffer[0] & 0x20)) {
  312. res = 1;
  313. intp = 1;
  314. }
  315. if (0 != (buffer[0] & 0x10)) {
  316. res = 1;
  317. intl = 1;
  318. }
  319. if (1 == res) {
  320. if ((1 == intp) && (0 == intl))
  321. buffer[0] = (TAOS_TRITON_CMD_REG | TAOS_TRITON_CMD_SPL_FN | 0x05);
  322. else if ((0 == intp) && (1 == intl))
  323. buffer[0] = (TAOS_TRITON_CMD_REG | TAOS_TRITON_CMD_SPL_FN | 0x06);
  324. else
  325. buffer[0] = (TAOS_TRITON_CMD_REG | TAOS_TRITON_CMD_SPL_FN | 0x07);
  326. res = APDS9930_i2c_master_operate(client, buffer, 0x1, I2C_FLAG_WRITE);
  327. if (res <= 0)
  328. goto EXIT_ERR;
  329. else
  330. res = 0;
  331. }
  332. return res;
  333. EXIT_ERR:
  334. APS_ERR("APDS9930_check_and_clear_intr fail\n");
  335. return 1;
  336. }
  337. /*----------------------------------------------------------------------------*/
  338. /*yucong add for interrupt mode support MTK inc 2012.3.7*/
  339. static int APDS9930_check_intr(struct i2c_client *client)
  340. {
  341. int res, intp, intl;
  342. u8 buffer[2];
  343. /* gpio_direction_input(alsps_int_gpio_number);
  344. if (gpio_get_value(alsps_int_gpio_number) == 1) //skip if no interrupt
  345. return 0;
  346. */
  347. buffer[0] = APDS9930_CMM_STATUS;
  348. res = APDS9930_i2c_master_operate(client, buffer, 0x101, I2C_FLAG_READ);
  349. if (res <= 0)
  350. goto EXIT_ERR;
  351. res = 0;
  352. intp = 0;
  353. intl = 0;
  354. if (0 != (buffer[0] & 0x20)) {
  355. res = 0;
  356. intp = 1;
  357. }
  358. if (0 != (buffer[0] & 0x10)) {
  359. res = 0;
  360. intl = 1;
  361. }
  362. return res;
  363. EXIT_ERR:
  364. APS_ERR("APDS9930_check_intr fail\n");
  365. return 1;
  366. }
  367. static int APDS9930_clear_intr(struct i2c_client *client)
  368. {
  369. int res;
  370. u8 buffer[2];
  371. buffer[0] = (TAOS_TRITON_CMD_REG | TAOS_TRITON_CMD_SPL_FN | 0x07);
  372. res = APDS9930_i2c_master_operate(client, buffer, 0x1, I2C_FLAG_WRITE);
  373. if (res <= 0)
  374. goto EXIT_ERR;
  375. else
  376. res = 0;
  377. return res;
  378. EXIT_ERR:
  379. APS_ERR("APDS9930_check_and_clear_intr fail\n");
  380. return 1;
  381. }
  382. static irqreturn_t alsps_interrupt_handler(int irq, void *dev_id)
  383. {
  384. struct APDS9930_priv *obj = g_APDS9930_ptr;
  385. if (!obj)
  386. return IRQ_HANDLED;
  387. disable_irq_nosync(alsps_irq);
  388. int_top_time = sched_clock();
  389. schedule_work(&obj->irq_work);
  390. return IRQ_HANDLED;
  391. }
  392. int APDS9930_irq_registration(struct i2c_client *client)
  393. {
  394. int ret = -1;
  395. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  396. /*struct task_struct *thread = NULL;*/
  397. struct pinctrl *pinctrl;
  398. struct pinctrl_state *pins_default;
  399. struct pinctrl_state *pins_cfg;
  400. struct platform_device *alsps_pdev = get_alsps_platformdev();
  401. u32 ints[2] = {0,0};
  402. g_APDS9930_ptr = obj;
  403. /* gpio setting */
  404. pinctrl = devm_pinctrl_get(&alsps_pdev->dev);
  405. if (IS_ERR(pinctrl)) {
  406. ret = PTR_ERR(pinctrl);
  407. APS_ERR("Cannot find alsps pinctrl!\n");
  408. }
  409. pins_default = pinctrl_lookup_state(pinctrl, "pin_default");
  410. if (IS_ERR(pins_default)) {
  411. ret = PTR_ERR(pins_default);
  412. APS_ERR("Cannot find alsps pinctrl default!\n");
  413. }
  414. pins_cfg = pinctrl_lookup_state(pinctrl, "pin_cfg");
  415. if (IS_ERR(pins_cfg)) {
  416. ret = PTR_ERR(pins_cfg);
  417. APS_ERR("Cannot find alsps pinctrl pin_cfg!\n");
  418. }
  419. pinctrl_select_state(pinctrl, pins_cfg);
  420. if (APDS9930_obj->irq_node) {
  421. of_property_read_u32_array(APDS9930_obj->irq_node, "debounce", ints, ARRAY_SIZE(ints));
  422. gpio_request(ints[0], "p-sensor");
  423. gpio_set_debounce(ints[0], ints[1]);
  424. APS_LOG("ints[0] = %d, ints[1] = %d!!\n", ints[0], ints[1]);
  425. alsps_irq = irq_of_parse_and_map(APDS9930_obj->irq_node, 0);
  426. if (alsps_irq < 0) {
  427. APS_ERR("alsps request_irq IRQ LINE NOT AVAILABLE!.");
  428. return -1;
  429. }
  430. APS_LOG("alsps_irq : %d\n", alsps_irq);
  431. /*gpio_direction_input(alsps_int_gpio_number);*/
  432. ret = request_irq(alsps_irq, alsps_interrupt_handler, IRQF_TRIGGER_NONE, "ALS-eint", NULL);
  433. if (ret > 0) {
  434. APS_ERR("alsps request_irq IRQ LINE NOT AVAILABLE!.");
  435. return ret;
  436. }
  437. }else {
  438. APS_ERR("null irq node!!\n");
  439. return -EINVAL;
  440. }
  441. /* disable_irq_nosync(alsps_irq);*/
  442. /* enable_irq(alsps_irq);*/
  443. return ret;
  444. }
  445. /*----------------------------------------------------------------------------*/
  446. static int APDS9930_init_client(struct i2c_client *client)
  447. {
  448. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  449. u8 databuf[2];
  450. int res = 0;
  451. databuf[0] = (TAOS_TRITON_CMD_REG | TAOS_TRITON_CMD_SPL_FN | 0x00);
  452. res = APDS9930_i2c_master_operate(client, databuf, 0x1, I2C_FLAG_WRITE);
  453. if (res <= 0)
  454. goto EXIT_ERR;
  455. databuf[0] = APDS9930_CMM_ENABLE;
  456. if (obj->hw->polling_mode_ps == 1)
  457. databuf[1] = 0x08;
  458. if (obj->hw->polling_mode_ps == 0)
  459. databuf[1] = 0x28;
  460. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  461. if (res <= 0)
  462. goto EXIT_ERR;
  463. databuf[0] = APDS9930_CMM_ATIME;
  464. databuf[1] = 0xF6;
  465. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  466. if (res <= 0)
  467. goto EXIT_ERR;
  468. databuf[0] = APDS9930_CMM_PTIME;
  469. databuf[1] = 0xFF;
  470. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  471. if (res <= 0)
  472. goto EXIT_ERR;
  473. databuf[0] = APDS9930_CMM_WTIME;
  474. databuf[1] = 0xFC;
  475. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  476. if (res <= 0)
  477. goto EXIT_ERR;
  478. /*for interrupt work mode support -- by liaoxl.lenovo 12.08.2011 */
  479. if (0 == obj->hw->polling_mode_ps) {
  480. if (1 == ps_cali.valid) {
  481. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  482. databuf[1] = (u8) (ps_cali.far_away & 0x00FF);
  483. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  484. if (res <= 0)
  485. goto EXIT_ERR;
  486. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  487. databuf[1] = (u8) ((ps_cali.far_away & 0xFF00) >> 8);
  488. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  489. if (res <= 0)
  490. goto EXIT_ERR;
  491. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  492. databuf[1] = (u8) (ps_cali.close & 0x00FF);
  493. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  494. if (res <= 0)
  495. goto EXIT_ERR;
  496. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  497. databuf[1] = (u8) ((ps_cali.close & 0xFF00) >> 8);
  498. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  499. if (res <= 0)
  500. goto EXIT_ERR;
  501. } else {
  502. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  503. databuf[1] = (u8)(750 & 0x00FF);
  504. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  505. if (res <= 0)
  506. goto EXIT_ERR;
  507. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  508. databuf[1] = (u8)((750 & 0xFF00) >> 8);
  509. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  510. if (res <= 0)
  511. goto EXIT_ERR;
  512. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  513. databuf[1] = (u8)(900 & 0x00FF);
  514. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  515. if (res <= 0)
  516. goto EXIT_ERR;
  517. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  518. databuf[1] = (u8)((900 & 0xFF00) >> 8);
  519. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  520. if (res <= 0)
  521. goto EXIT_ERR;
  522. }
  523. databuf[0] = APDS9930_CMM_Persistence;
  524. databuf[1] = 0x20;
  525. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  526. if (res <= 0)
  527. goto EXIT_ERR;
  528. }
  529. databuf[0] = APDS9930_CMM_CONFIG;
  530. databuf[1] = 0x00;
  531. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  532. if (res <= 0)
  533. goto EXIT_ERR;
  534. /*Lenovo-sw chenlj2 add 2011-06-03,modified pulse 2 to 4 */
  535. databuf[0] = APDS9930_CMM_PPCOUNT;
  536. databuf[1] = APDS9930_CMM_PPCOUNT_VALUE;
  537. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  538. if (res <= 0)
  539. goto EXIT_ERR;
  540. /*Lenovo-sw chenlj2 add 2011-06-03,modified gain 16 to 1 */
  541. databuf[0] = APDS9930_CMM_CONTROL;
  542. databuf[1] = APDS9930_CMM_CONTROL_VALUE;
  543. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  544. if (res <= 0)
  545. goto EXIT_ERR;
  546. res = APDS9930_irq_registration(client);
  547. if (res != 0) {
  548. APS_ERR("registration failed: %d\n", res);
  549. return res;
  550. }
  551. res = APDS9930_check_and_clear_intr(client);
  552. if (res) {
  553. APS_ERR("check/clear intr: %d\n", res);
  554. return res;
  555. }
  556. return APDS9930_SUCCESS;
  557. EXIT_ERR:
  558. APS_ERR("init dev: %d\n", res);
  559. return res;
  560. }
  561. /******************************************************************************
  562. * Function Configuration
  563. ******************************************************************************/
  564. int APDS9930_read_als(struct i2c_client *client, u16 *data)
  565. {
  566. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  567. u16 c0_value, c1_value;
  568. u32 c0_nf, c1_nf;
  569. u8 buffer[2];
  570. u16 atio;
  571. int res = 0;
  572. if (client == NULL) {
  573. APS_DBG("CLIENT CANN'T EQUL NULL\n");
  574. return -1;
  575. }
  576. buffer[0] = APDS9930_CMM_C0DATA_L;
  577. res = APDS9930_i2c_master_operate(client, buffer, 0x201, I2C_FLAG_READ);
  578. if (res <= 0)
  579. goto EXIT_ERR;
  580. c0_value = buffer[0] | (buffer[1] << 8);
  581. c0_nf = obj->als_modulus * c0_value;
  582. /* APS_LOG("c0_value=%d, c0_nf=%d, als_modulus=%d\n", c0_value, c0_nf, obj->als_modulus); */
  583. buffer[0] = APDS9930_CMM_C1DATA_L;
  584. res = APDS9930_i2c_master_operate(client, buffer, 0x201, I2C_FLAG_READ);
  585. if (res <= 0)
  586. goto EXIT_ERR;
  587. c1_value = buffer[0] | (buffer[1] << 8);
  588. c1_nf = obj->als_modulus * c1_value;
  589. /* APS_LOG("c1_value=%d, c1_nf=%d, als_modulus=%d\n", c1_value, c1_nf, obj->als_modulus); */
  590. if ((c0_value > c1_value) && (c0_value < 50000)) { /*Lenovo-sw chenlj2 add 2011-06-03,add { */
  591. atio = (c1_nf * 100) / c0_nf;
  592. /* APS_LOG("atio = %d\n", atio); */
  593. if (atio < 30) {
  594. *data = (13 * c0_nf - 24 * c1_nf) / 10000;
  595. } else if (atio >= 30 && atio < 38) { /*Lenovo-sw chenlj2 add 2011-06-03,modify > to >= */
  596. *data = (16 * c0_nf - 35 * c1_nf) / 10000;
  597. } else if (atio >= 38 && atio < 45) { /*Lenovo-sw chenlj2 add 2011-06-03,modify > to >= */
  598. *data = (9 * c0_nf - 17 * c1_nf) / 10000;
  599. } else if (atio >= 45 && atio < 54) { /*Lenovo-sw chenlj2 add 2011-06-03,modify > to >= */
  600. *data = (6 * c0_nf - 10 * c1_nf) / 10000;
  601. } else
  602. *data = 0;
  603. /*Lenovo-sw chenlj2 add 2011-06-03,add } */
  604. } else if (c0_value > 50000) {
  605. *data = 65535;
  606. } else if (c0_value == 0) {
  607. *data = 0;
  608. } else {
  609. APS_DBG("APDS9930_read_als als_value is invalid!!\n");
  610. return -1;
  611. }
  612. /* APS_LOG("APDS9930_read_als als_value_lux = %d\n", *data); */
  613. return 0;
  614. EXIT_ERR:
  615. APS_ERR("APDS9930_read_ps fail\n");
  616. return res;
  617. }
  618. int APDS9930_read_als_ch0(struct i2c_client *client, u16 *data)
  619. {
  620. /* struct APDS9930_priv *obj = i2c_get_clientdata(client); */
  621. u16 c0_value;
  622. u8 buffer[2];
  623. int res = 0;
  624. if (client == NULL) {
  625. APS_DBG("CLIENT CANN'T EQUL NULL\n");
  626. return -1;
  627. }
  628. /* get adc channel 0 value */
  629. buffer[0] = APDS9930_CMM_C0DATA_L;
  630. res = APDS9930_i2c_master_operate(client, buffer, 0x201, I2C_FLAG_READ);
  631. if (res <= 0)
  632. goto EXIT_ERR;
  633. c0_value = buffer[0] | (buffer[1] << 8);
  634. *data = c0_value;
  635. /* APS_LOG("c0_value=%d\n", c0_value); */
  636. return 0;
  637. EXIT_ERR:
  638. APS_ERR("APDS9930_read_ps fail\n");
  639. return res;
  640. }
  641. /*----------------------------------------------------------------------------*/
  642. static int APDS9930_get_als_value(struct APDS9930_priv *obj, u16 als)
  643. {
  644. int idx;
  645. int invalid = 0;
  646. for (idx = 0; idx < obj->als_level_num; idx++) {
  647. if (als < obj->hw->als_level[idx])
  648. break;
  649. }
  650. if (idx >= obj->als_value_num) {
  651. APS_ERR("APDS9930_get_als_value exceed range\n");
  652. idx = obj->als_value_num - 1;
  653. }
  654. if (1 == atomic_read(&obj->als_deb_on)) {
  655. unsigned long endt = atomic_read(&obj->als_deb_end);
  656. if (time_after(jiffies, endt))
  657. atomic_set(&obj->als_deb_on, 0);
  658. if (1 == atomic_read(&obj->als_deb_on))
  659. invalid = 1;
  660. }
  661. if (!invalid) {
  662. #if defined(MTK_AAL_SUPPORT)
  663. int level_high = obj->hw->als_level[idx];
  664. int level_low = (idx > 0) ? obj->hw->als_level[idx - 1] : 0;
  665. int level_diff = level_high - level_low;
  666. int value_high = obj->hw->als_value[idx];
  667. int value_low = (idx > 0) ? obj->hw->als_value[idx - 1] : 0;
  668. int value_diff = value_high - value_low;
  669. int value = 0;
  670. if ((level_low >= level_high) || (value_low >= value_high))
  671. value = value_low;
  672. else
  673. value =
  674. (level_diff * value_low + (als - level_low) * value_diff +
  675. ((level_diff + 1) >> 1)) / level_diff;
  676. APS_DBG("ALS: %d [%d, %d] => %d [%d, %d]\n", als, level_low, level_high, value,
  677. value_low, value_high);
  678. return value;
  679. #endif
  680. /* APS_ERR("ALS: %05d => %05d\n", als, obj->hw->als_value[idx]); */
  681. return obj->hw->als_value[idx];
  682. }
  683. /* APS_ERR("ALS: %05d => %05d (-1)\n", als, obj->hw->als_value[idx]); */
  684. return -1;
  685. }
  686. /*----------------------------------------------------------------------------*/
  687. long APDS9930_read_ps(struct i2c_client *client, u16 *data)
  688. {
  689. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  690. u8 buffer[2];
  691. u16 temp_data;
  692. long res = 0;
  693. if (client == NULL) {
  694. APS_DBG("CLIENT CANN'T EQUL NULL\n");
  695. return -1;
  696. }
  697. buffer[0] = APDS9930_CMM_PDATA_L;
  698. res = APDS9930_i2c_master_operate(client, buffer, 0x201, I2C_FLAG_READ);
  699. if (res <= 0)
  700. goto EXIT_ERR;
  701. temp_data = buffer[0] | (buffer[1] << 8);
  702. if (temp_data < obj->ps_cali)
  703. *data = 0;
  704. else
  705. *data = temp_data - obj->ps_cali;
  706. return 0;
  707. EXIT_ERR:
  708. APS_ERR("APDS9930_read_ps fail\n");
  709. return res;
  710. }
  711. /*----------------------------------------------------------------------------*/
  712. static int APDS9930_get_ps_value(struct APDS9930_priv *obj, u16 ps)
  713. {
  714. int val; /* mask = atomic_read(&obj->ps_mask); */
  715. int invalid = 0;
  716. static int val_temp = 1;
  717. if (ps_cali.valid == 1) {
  718. if (ps > ps_cali.close) {
  719. val = 0; /*close */
  720. val_temp = 0;
  721. intr_flag_value = 1;
  722. }
  723. else if (ps < ps_cali.far_away) {
  724. val = 1; /*far away */
  725. val_temp = 1;
  726. intr_flag_value = 0;
  727. } else
  728. val = val_temp;
  729. APS_LOG("APDS9930_get_ps_value val = %d", val);
  730. } else {
  731. if (ps > atomic_read(&obj->ps_thd_val_high)) {
  732. val = 0; /*close */
  733. val_temp = 0;
  734. intr_flag_value = 1;
  735. } else if (ps < atomic_read(&obj->ps_thd_val_low)) {
  736. val = 1; /*far away */
  737. val_temp = 1;
  738. intr_flag_value = 0;
  739. } else
  740. val = val_temp;
  741. }
  742. if (atomic_read(&obj->ps_suspend)) {
  743. invalid = 1;
  744. } else if (1 == atomic_read(&obj->ps_deb_on)) {
  745. unsigned long endt = atomic_read(&obj->ps_deb_end);
  746. if (time_after(jiffies, endt))
  747. atomic_set(&obj->ps_deb_on, 0);
  748. if (1 == atomic_read(&obj->ps_deb_on))
  749. invalid = 1;
  750. } else if (obj->als > 45000) {
  751. /* invalid = 1; */
  752. APS_DBG("ligh too high will result to failt proximiy\n");
  753. return 1; /*far away */
  754. }
  755. if (!invalid) {
  756. /* APS_DBG("PS: %05d => %05d\n", ps, val); */
  757. return val;
  758. } else {
  759. return -1;
  760. }
  761. }
  762. /*----------------------------------------------------------------------------*/
  763. /*for interrupt work mode support -- by liaoxl.lenovo 12.08.2011*/
  764. /* #define DEBUG_APDS9930 */
  765. static void APDS9930_irq_work(struct work_struct *work)
  766. {
  767. struct APDS9930_priv *obj =
  768. (struct APDS9930_priv *)container_of(work, struct APDS9930_priv, irq_work);
  769. int err;
  770. /*struct hwm_sensor_data sensor_data;*/
  771. int intFlag = -1;
  772. u8 databuf[3];
  773. int res = 0;
  774. err = APDS9930_check_intr(obj->client);
  775. if (err) {
  776. APS_ERR("APDS9930_irq_work check intrs: %d\n", err);
  777. } else {
  778. /* get raw data */
  779. APDS9930_read_ps(obj->client, &obj->ps);
  780. APDS9930_read_als_ch0(obj->client, &obj->als);
  781. APS_LOG("APDS9930_irq_work rawdata ps=%d als_ch0=%d!\n", obj->ps, obj->als);
  782. APS_LOG("APDS9930 int top half time = %lld\n", int_top_time);
  783. if (obj->als > 40000) {
  784. APS_LOG("APDS9930_irq_work ALS too large may under lighting als_ch0=%d!\n",
  785. obj->als);
  786. enable_irq(alsps_irq);
  787. return;
  788. }
  789. intFlag = APDS9930_get_ps_value(obj, obj->ps);
  790. /*
  791. sensor_data.values[0] = APDS9930_get_ps_value(obj, obj->ps);
  792. sensor_data.value_divide = 1;
  793. sensor_data.status = SENSOR_STATUS_ACCURACY_MEDIUM;
  794. */
  795. #ifdef DEBUG_APDS9930
  796. databuf[0] = APDS9930_CMM_ENABLE;
  797. res = APDS9930_i2c_master_operate(obj->client, databuf, 0x101, I2C_FLAG_READ);
  798. if (res <= 0)
  799. goto EXIT_ERR;
  800. APS_LOG("APDS9930_irq_work APDS9930_CMM_ENABLE ps value = %x\n", databuf[0]);
  801. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  802. res = APDS9930_i2c_master_operate(obj->client, databuf, 0x201, I2C_FLAG_READ);
  803. if (res <= 0)
  804. goto EXIT_ERR;
  805. APS_LOG
  806. ("APDS9930_irq_work APDS9930_CMM_INT_LOW_THD_LOW before databuf[0]=%d databuf[1]=%d!\n",
  807. databuf[0], databuf[1]);
  808. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  809. res = APDS9930_i2c_master_operate(obj->client, databuf, 0x201, I2C_FLAG_READ);
  810. if (res <= 0)
  811. goto EXIT_ERR;
  812. APS_LOG
  813. ("APDS9930_irq_work APDS9930_CMM_INT_HIGH_THD_LOW before databuf[0]=%d databuf[1]=%d!\n",
  814. databuf[0], databuf[1]);
  815. #endif
  816. /*signal interrupt function add*/
  817. if (intr_flag_value) {
  818. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  819. databuf[1] = (u8) ((atomic_read(&obj->ps_thd_val_low)) & 0x00FF);
  820. res =
  821. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  822. if (res <= 0)
  823. goto EXIT_ERR;
  824. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  825. databuf[1] = (u8) (((atomic_read(&obj->ps_thd_val_low)) & 0xFF00) >> 8);
  826. res =
  827. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  828. if (res <= 0)
  829. goto EXIT_ERR;
  830. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  831. databuf[1] = (u8) (0x00FF);
  832. res =
  833. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  834. if (res <= 0)
  835. goto EXIT_ERR;
  836. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  837. databuf[1] = (u8) ((0xFF00) >> 8);
  838. res =
  839. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  840. if (res <= 0)
  841. goto EXIT_ERR;
  842. } else {
  843. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  844. databuf[1] = (u8) (0 & 0x00FF);
  845. res =
  846. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  847. if (res <= 0)
  848. goto EXIT_ERR;
  849. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  850. databuf[1] = (u8) ((0 & 0xFF00) >> 8);
  851. res =
  852. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  853. if (res <= 0)
  854. goto EXIT_ERR;
  855. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  856. databuf[1] = (u8) ((atomic_read(&obj->ps_thd_val_high)) & 0x00FF);
  857. res =
  858. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  859. if (res <= 0)
  860. goto EXIT_ERR;
  861. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  862. databuf[1] = (u8) (((atomic_read(&obj->ps_thd_val_high)) & 0xFF00) >> 8);
  863. res =
  864. APDS9930_i2c_master_operate(obj->client, databuf, 0x2, I2C_FLAG_WRITE);
  865. res = i2c_master_send(obj->client, databuf, 0x2);
  866. if (res <= 0)
  867. goto EXIT_ERR;
  868. }
  869. /* let up layer to know */
  870. #ifdef DEBUG_APDS9930
  871. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  872. res = APDS9930_i2c_master_operate(obj->client, databuf, 0x201, I2C_FLAG_READ);
  873. if (res <= 0)
  874. goto EXIT_ERR;
  875. APS_LOG
  876. ("APDS9930_irq_work APDS9930_CMM_INT_LOW_THD_LOW after databuf[0]=%d databuf[1]=%d!\n",
  877. databuf[0], databuf[1]);
  878. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  879. res = APDS9930_i2c_master_operate(obj->client, databuf, 0x201, I2C_FLAG_READ);
  880. if (res <= 0)
  881. goto EXIT_ERR;
  882. APS_LOG
  883. ("APDS9930_irq_work APDS9930_CMM_INT_HIGH_THD_LOW after databuf[0]=%d databuf[1]=%d!\n",
  884. databuf[0], databuf[1]);
  885. #endif
  886. res = ps_report_interrupt_data(intFlag);
  887. if (res)
  888. APS_ERR("apds9930 call ps_report_interrupt_data fail = %d\n", res);
  889. /*err = hwmsen_get_interrupt_data(ID_PROXIMITY, &sensor_data);
  890. if (err)
  891. APS_ERR("call hwmsen_get_interrupt_data fail = %d\n", err);*/
  892. }
  893. APDS9930_clear_intr(obj->client);
  894. /* disable_irq_nosync(alsps_irq);*/
  895. enable_irq(alsps_irq);
  896. return;
  897. EXIT_ERR:
  898. APDS9930_clear_intr(obj->client);
  899. /* disable_irq_nosync(alsps_irq);*/
  900. enable_irq(alsps_irq);
  901. APS_ERR("i2c_transfer error = %d\n", res);
  902. }
  903. /******************************************************************************
  904. * Function Configuration
  905. ******************************************************************************/
  906. static int APDS9930_open(struct inode *inode, struct file *file)
  907. {
  908. file->private_data = APDS9930_i2c_client;
  909. if (!file->private_data) {
  910. APS_ERR("null pointer!!\n");
  911. return -EINVAL;
  912. }
  913. return nonseekable_open(inode, file);
  914. }
  915. /*----------------------------------------------------------------------------*/
  916. static int APDS9930_release(struct inode *inode, struct file *file)
  917. {
  918. file->private_data = NULL;
  919. return 0;
  920. }
  921. /*----------------------------------------------------------------------------*/
  922. static int set_psensor_threshold(struct i2c_client *client)
  923. {
  924. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  925. u8 databuf[3];
  926. int res = 0;
  927. APS_ERR("set_psensor_threshold function high: 0x%x, low:0x%x\n",
  928. atomic_read(&obj->ps_thd_val_high), atomic_read(&obj->ps_thd_val_low));
  929. databuf[0] = APDS9930_CMM_INT_LOW_THD_LOW;
  930. databuf[1] = (u8) (atomic_read(&obj->ps_thd_val_low) & 0x00FF);
  931. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  932. if (res <= 0)
  933. return -1;
  934. databuf[0] = APDS9930_CMM_INT_LOW_THD_HIGH;
  935. databuf[1] = (u8) ((atomic_read(&obj->ps_thd_val_low) & 0xFF00) >> 8);
  936. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  937. if (res <= 0)
  938. return -1;
  939. databuf[0] = APDS9930_CMM_INT_HIGH_THD_LOW;
  940. databuf[1] = (u8) (atomic_read(&obj->ps_thd_val_high) & 0x00FF);
  941. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  942. if (res <= 0)
  943. return -1;
  944. databuf[0] = APDS9930_CMM_INT_HIGH_THD_HIGH;
  945. databuf[1] = (u8) ((atomic_read(&obj->ps_thd_val_high) & 0xFF00) >> 8);
  946. res = APDS9930_i2c_master_operate(client, databuf, 0x2, I2C_FLAG_WRITE);
  947. if (res <= 0)
  948. return -1;
  949. return 0;
  950. }
  951. /*----------------------------------------------------------------------------*/
  952. static long APDS9930_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  953. {
  954. struct i2c_client *client = (struct i2c_client *)file->private_data;
  955. struct APDS9930_priv *obj = i2c_get_clientdata(client);
  956. long err = 0;
  957. void __user *ptr = (void __user *)arg;
  958. int dat;
  959. uint32_t enable;
  960. int ps_result;
  961. int ps_cali;
  962. int threshold[2];
  963. switch (cmd) {
  964. case ALSPS_SET_PS_MODE:
  965. if (copy_from_user(&enable, ptr, sizeof(enable))) {
  966. err = -EFAULT;
  967. goto err_out;
  968. }
  969. if (enable) {
  970. err = APDS9930_enable_ps(obj->client, 1);
  971. if (err) {
  972. APS_ERR("enable ps fail: %ld\n", err);
  973. goto err_out;
  974. }
  975. set_bit(CMC_BIT_PS, &obj->enable);
  976. } else {
  977. err = APDS9930_enable_ps(obj->client, 0);
  978. if (err) {
  979. APS_ERR("disable ps fail: %ld\n", err);
  980. goto err_out;
  981. }
  982. clear_bit(CMC_BIT_PS, &obj->enable);
  983. }
  984. break;
  985. case ALSPS_GET_PS_MODE:
  986. enable = test_bit(CMC_BIT_PS, &obj->enable) ? (1) : (0);
  987. if (copy_to_user(ptr, &enable, sizeof(enable))) {
  988. err = -EFAULT;
  989. goto err_out;
  990. }
  991. break;
  992. case ALSPS_GET_PS_DATA:
  993. err = APDS9930_read_ps(obj->client, &obj->ps);
  994. if (err)
  995. goto err_out;
  996. dat = APDS9930_get_ps_value(obj, obj->ps);
  997. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  998. err = -EFAULT;
  999. goto err_out;
  1000. }
  1001. break;
  1002. case ALSPS_GET_PS_RAW_DATA:
  1003. err = APDS9930_read_ps(obj->client, &obj->ps);
  1004. if (err)
  1005. goto err_out;
  1006. dat = obj->ps;
  1007. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1008. err = -EFAULT;
  1009. goto err_out;
  1010. }
  1011. break;
  1012. case ALSPS_SET_ALS_MODE:
  1013. if (copy_from_user(&enable, ptr, sizeof(enable))) {
  1014. err = -EFAULT;
  1015. goto err_out;
  1016. }
  1017. if (enable) {
  1018. err = APDS9930_enable_als(obj->client, 1);
  1019. if (err) {
  1020. APS_ERR("enable als fail: %ld\n", err);
  1021. goto err_out;
  1022. }
  1023. set_bit(CMC_BIT_ALS, &obj->enable);
  1024. } else {
  1025. err = APDS9930_enable_als(obj->client, 0);
  1026. if (err) {
  1027. APS_ERR("disable als fail: %ld\n", err);
  1028. goto err_out;
  1029. }
  1030. clear_bit(CMC_BIT_ALS, &obj->enable);
  1031. }
  1032. break;
  1033. case ALSPS_GET_ALS_MODE:
  1034. enable = test_bit(CMC_BIT_ALS, &obj->enable) ? (1) : (0);
  1035. if (copy_to_user(ptr, &enable, sizeof(enable))) {
  1036. err = -EFAULT;
  1037. goto err_out;
  1038. }
  1039. break;
  1040. case ALSPS_GET_ALS_DATA:
  1041. err = APDS9930_read_als(obj->client, &obj->als);
  1042. if (err)
  1043. goto err_out;
  1044. dat = APDS9930_get_als_value(obj, obj->als);
  1045. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1046. err = -EFAULT;
  1047. goto err_out;
  1048. }
  1049. break;
  1050. case ALSPS_GET_ALS_RAW_DATA:
  1051. err = APDS9930_read_als(obj->client, &obj->als);
  1052. if (err)
  1053. goto err_out;
  1054. dat = obj->als;
  1055. if (copy_to_user(ptr, &dat, sizeof(dat))) {
  1056. err = -EFAULT;
  1057. goto err_out;
  1058. }
  1059. break;
  1060. /*----------------------------------for factory mode test---------------------------------------*/
  1061. case ALSPS_GET_PS_TEST_RESULT:
  1062. err = APDS9930_read_ps(obj->client, &obj->ps);
  1063. if (err)
  1064. goto err_out;
  1065. if (obj->ps > atomic_read(&obj->ps_thd_val_high))
  1066. ps_result = 0;
  1067. else
  1068. ps_result = 1;
  1069. if (copy_to_user(ptr, &ps_result, sizeof(ps_result))) {
  1070. err = -EFAULT;
  1071. goto err_out;
  1072. }
  1073. break;
  1074. case ALSPS_IOCTL_CLR_CALI:
  1075. if (copy_from_user(&dat, ptr, sizeof(dat))) {
  1076. err = -EFAULT;
  1077. goto err_out;
  1078. }
  1079. if (dat == 0)
  1080. obj->ps_cali = 0;
  1081. break;
  1082. case ALSPS_IOCTL_GET_CALI:
  1083. ps_cali = obj->ps_cali;
  1084. if (copy_to_user(ptr, &ps_cali, sizeof(ps_cali))) {
  1085. err = -EFAULT;
  1086. goto err_out;
  1087. }
  1088. break;
  1089. case ALSPS_IOCTL_SET_CALI:
  1090. if (copy_from_user(&ps_cali, ptr, sizeof(ps_cali))) {
  1091. err = -EFAULT;
  1092. goto err_out;
  1093. }
  1094. obj->ps_cali = ps_cali;
  1095. break;
  1096. case ALSPS_SET_PS_THRESHOLD:
  1097. if (copy_from_user(threshold, ptr, sizeof(threshold))) {
  1098. err = -EFAULT;
  1099. goto err_out;
  1100. }
  1101. APS_ERR("%s set threshold high: 0x%x, low: 0x%x\n", __func__, threshold[0],
  1102. threshold[1]);
  1103. atomic_set(&obj->ps_thd_val_high, (threshold[0] + obj->ps_cali));
  1104. atomic_set(&obj->ps_thd_val_low, (threshold[1] + obj->ps_cali)); /* need to confirm */
  1105. set_psensor_threshold(obj->client);
  1106. break;
  1107. case ALSPS_GET_PS_THRESHOLD_HIGH:
  1108. threshold[0] = atomic_read(&obj->ps_thd_val_high) - obj->ps_cali;
  1109. APS_ERR("%s get threshold high: 0x%x\n", __func__, threshold[0]);
  1110. if (copy_to_user(ptr, &threshold[0], sizeof(threshold[0]))) {
  1111. err = -EFAULT;
  1112. goto err_out;
  1113. }
  1114. break;
  1115. case ALSPS_GET_PS_THRESHOLD_LOW:
  1116. threshold[0] = atomic_read(&obj->ps_thd_val_low) - obj->ps_cali;
  1117. APS_ERR("%s get threshold low: 0x%x\n", __func__, threshold[0]);
  1118. if (copy_to_user(ptr, &threshold[0], sizeof(threshold[0]))) {
  1119. err = -EFAULT;
  1120. goto err_out;
  1121. }
  1122. break;
  1123. /*------------------------------------------------------------------------------------------*/
  1124. default:
  1125. APS_ERR("%s not supported = 0x%04x", __func__, cmd);
  1126. err = -ENOIOCTLCMD;
  1127. break;
  1128. }
  1129. err_out:
  1130. return err;
  1131. }
  1132. /*----------------------------------------------------------------------------*/
  1133. static const struct file_operations APDS9930_fops = {
  1134. .owner = THIS_MODULE,
  1135. .open = APDS9930_open,
  1136. .release = APDS9930_release,
  1137. .unlocked_ioctl = APDS9930_unlocked_ioctl,
  1138. };
  1139. /*----------------------------------------------------------------------------*/
  1140. static struct miscdevice APDS9930_device = {
  1141. .minor = MISC_DYNAMIC_MINOR,
  1142. .name = "als_ps",
  1143. .fops = &APDS9930_fops,
  1144. };
  1145. /*----------------------------------------------------------------------------*/
  1146. static int APDS9930_i2c_suspend(struct i2c_client *client, pm_message_t msg)
  1147. {
  1148. /* struct APDS9930_priv *obj = i2c_get_clientdata(client); */
  1149. /* int err; */
  1150. APS_FUN();
  1151. #if 0
  1152. if (msg.event == PM_EVENT_SUSPEND) {
  1153. if (!obj) {
  1154. APS_ERR("null pointer!!\n");
  1155. return -EINVAL;
  1156. }
  1157. atomic_set(&obj->als_suspend, 1);
  1158. err = APDS9930_enable_als(client, 0);
  1159. if (err) {
  1160. APS_ERR("disable als: %d\n", err);
  1161. return err;
  1162. }
  1163. atomic_set(&obj->ps_suspend, 1);
  1164. err = APDS9930_enable_ps(client, 0);
  1165. if (err) {
  1166. APS_ERR("disable ps: %d\n", err);
  1167. return err;
  1168. }
  1169. APDS9930_power(obj->hw, 0);
  1170. }
  1171. #endif
  1172. return 0;
  1173. }
  1174. /*----------------------------------------------------------------------------*/
  1175. static int APDS9930_i2c_resume(struct i2c_client *client)
  1176. {
  1177. /* struct APDS9930_priv *obj = i2c_get_clientdata(client); */
  1178. /* int err; */
  1179. APS_FUN();
  1180. #if 0
  1181. if (!obj) {
  1182. APS_ERR("null pointer!!\n");
  1183. return -EINVAL;
  1184. }
  1185. APDS9930_power(obj->hw, 1);
  1186. err = APDS9930_init_client(client);
  1187. if (err) {
  1188. APS_ERR("initialize client fail!!\n");
  1189. return err;
  1190. }
  1191. atomic_set(&obj->als_suspend, 0);
  1192. if (test_bit(CMC_BIT_ALS, &obj->enable)) {
  1193. err = APDS9930_enable_als(client, 1);
  1194. if (err)
  1195. APS_ERR("enable als fail: %d\n", err);
  1196. }
  1197. atomic_set(&obj->ps_suspend, 0);
  1198. if (test_bit(CMC_BIT_PS, &obj->enable)) {
  1199. err = APDS9930_enable_ps(client, 1);
  1200. if (err)
  1201. APS_ERR("enable ps fail: %d\n", err);
  1202. }
  1203. #endif
  1204. return 0;
  1205. }
  1206. /*----------------------------------------------------------------------------*/
  1207. #if defined(CONFIG_HAS_EARLYSUSPEND)
  1208. static void APDS9930_early_suspend(struct early_suspend *h)
  1209. { /*early_suspend is only applied for ALS */
  1210. struct APDS9930_priv *obj = container_of(h, struct APDS9930_priv, early_drv);
  1211. int err;
  1212. APS_FUN();
  1213. if (!obj) {
  1214. APS_ERR("null pointer!!\n");
  1215. return;
  1216. }
  1217. #if 1
  1218. atomic_set(&obj->als_suspend, 1);
  1219. if (test_bit(CMC_BIT_ALS, &obj->enable)) {
  1220. err = APDS9930_enable_als(obj->client, 0);
  1221. if (err)
  1222. APS_ERR("disable als fail: %d\n", err);
  1223. }
  1224. #endif
  1225. }
  1226. /*----------------------------------------------------------------------------*/
  1227. static void APDS9930_late_resume(struct early_suspend *h)
  1228. { /*early_suspend is only applied for ALS */
  1229. struct APDS9930_priv *obj = container_of(h, struct APDS9930_priv, early_drv);
  1230. int err;
  1231. APS_FUN();
  1232. if (!obj) {
  1233. APS_ERR("null pointer!!\n");
  1234. return;
  1235. }
  1236. #if 1
  1237. atomic_set(&obj->als_suspend, 0);
  1238. if (test_bit(CMC_BIT_ALS, &obj->enable)) {
  1239. err = APDS9930_enable_als(obj->client, 1);
  1240. if (err)
  1241. APS_ERR("enable als fail: %d\n", err);
  1242. }
  1243. #endif
  1244. }
  1245. #endif
  1246. /*----------------------------------------------------------------------------*/
  1247. static int temp_als;
  1248. static int ALS_FLAG;
  1249. int APDS9930_ps_operate(void *self, uint32_t command, void *buff_in, int size_in,
  1250. void *buff_out, int size_out, int *actualout)
  1251. {
  1252. int value;
  1253. int err = 0;
  1254. struct hwm_sensor_data *sensor_data;
  1255. struct APDS9930_priv *obj = (struct APDS9930_priv *)self;
  1256. /* APS_FUN(f); */
  1257. switch (command) {
  1258. case SENSOR_DELAY:
  1259. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1260. APS_ERR("Set delay parameter error!\n");
  1261. err = -EINVAL;
  1262. }
  1263. /* Do nothing */
  1264. break;
  1265. case SENSOR_ENABLE:
  1266. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1267. APS_ERR("Enable sensor parameter error!\n");
  1268. err = -EINVAL;
  1269. } else {
  1270. value = *(int *)buff_in;
  1271. if (value) {
  1272. err = APDS9930_enable_ps(obj->client, 1);
  1273. if (err) {
  1274. APS_ERR("enable ps fail: %d\n", err);
  1275. return -1;
  1276. }
  1277. set_bit(CMC_BIT_PS, &obj->enable);
  1278. #if 1
  1279. if (!test_bit(CMC_BIT_ALS, &obj->enable)) {
  1280. ALS_FLAG = 1;
  1281. err = APDS9930_enable_als(obj->client, 1);
  1282. if (err) {
  1283. APS_ERR("enable als fail: %d\n", err);
  1284. return -1;
  1285. }
  1286. }
  1287. #endif
  1288. } else {
  1289. err = APDS9930_enable_ps(obj->client, 0);
  1290. if (err) {
  1291. APS_ERR("disable ps fail: %d\n", err);
  1292. return -1;
  1293. }
  1294. clear_bit(CMC_BIT_PS, &obj->enable);
  1295. #if 1
  1296. if (ALS_FLAG == 1) {
  1297. err = APDS9930_enable_als(obj->client, 0);
  1298. if (err) {
  1299. APS_ERR("disable als fail: %d\n", err);
  1300. return -1;
  1301. }
  1302. ALS_FLAG = 0;
  1303. }
  1304. #endif
  1305. }
  1306. }
  1307. break;
  1308. case SENSOR_GET_DATA:
  1309. if ((buff_out == NULL) || (size_out < sizeof(struct hwm_sensor_data))) {
  1310. APS_ERR("get sensor data parameter error!\n");
  1311. err = -EINVAL;
  1312. } else {
  1313. sensor_data = (struct hwm_sensor_data *) buff_out;
  1314. APDS9930_read_ps(obj->client, &obj->ps);
  1315. APDS9930_read_als_ch0(obj->client, &obj->als);
  1316. APS_ERR("APDS9930_ps_operate als data=%d!\n", obj->als);
  1317. sensor_data->values[0] = APDS9930_get_ps_value(obj, obj->ps);
  1318. sensor_data->value_divide = 1;
  1319. sensor_data->status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1320. }
  1321. break;
  1322. default:
  1323. APS_ERR("proxmy sensor operate function no this parameter %d!\n", command);
  1324. err = -1;
  1325. break;
  1326. }
  1327. return err;
  1328. }
  1329. int APDS9930_als_operate(void *self, uint32_t command, void *buff_in, int size_in,
  1330. void *buff_out, int size_out, int *actualout)
  1331. {
  1332. int err = 0;
  1333. int value;
  1334. struct hwm_sensor_data *sensor_data;
  1335. struct APDS9930_priv *obj = (struct APDS9930_priv *)self;
  1336. switch (command) {
  1337. case SENSOR_DELAY:
  1338. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1339. APS_ERR("Set delay parameter error!\n");
  1340. err = -EINVAL;
  1341. }
  1342. /* Do nothing */
  1343. break;
  1344. case SENSOR_ENABLE:
  1345. if ((buff_in == NULL) || (size_in < sizeof(int))) {
  1346. APS_ERR("Enable sensor parameter error!\n");
  1347. err = -EINVAL;
  1348. } else {
  1349. value = *(int *)buff_in;
  1350. if (value) {
  1351. err = APDS9930_enable_als(obj->client, 1);
  1352. if (err) {
  1353. APS_ERR("enable als fail: %d\n", err);
  1354. return -1;
  1355. }
  1356. set_bit(CMC_BIT_ALS, &obj->enable);
  1357. } else {
  1358. err = APDS9930_enable_als(obj->client, 0);
  1359. if (err) {
  1360. APS_ERR("disable als fail: %d\n", err);
  1361. return -1;
  1362. }
  1363. clear_bit(CMC_BIT_ALS, &obj->enable);
  1364. }
  1365. }
  1366. break;
  1367. case SENSOR_GET_DATA:
  1368. if ((buff_out == NULL) || (size_out < sizeof(struct hwm_sensor_data))) {
  1369. APS_ERR("get sensor data parameter error!\n");
  1370. err = -EINVAL;
  1371. } else {
  1372. sensor_data = (struct hwm_sensor_data *) buff_out;
  1373. /*yucong MTK add for fixing known issue */
  1374. APDS9930_read_als(obj->client, &obj->als);
  1375. if (obj->als == 0) {
  1376. sensor_data->values[0] = temp_als;
  1377. } else {
  1378. u16 b[2];
  1379. int i;
  1380. for (i = 0; i < 2; i++) {
  1381. APDS9930_read_als(obj->client, &obj->als);
  1382. b[i] = obj->als;
  1383. }
  1384. (b[1] > b[0]) ? (obj->als = b[0]) : (obj->als = b[1]);
  1385. sensor_data->values[0] = APDS9930_get_als_value(obj, obj->als);
  1386. temp_als = sensor_data->values[0];
  1387. }
  1388. sensor_data->value_divide = 1;
  1389. sensor_data->status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1390. }
  1391. break;
  1392. default:
  1393. APS_ERR("light sensor operate function no this parameter %d!\n", command);
  1394. err = -1;
  1395. break;
  1396. }
  1397. return err;
  1398. }
  1399. /*----------------------------------------------------------------------------*/
  1400. static int APDS9930_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
  1401. {
  1402. strcpy(info->type, APDS9930_DEV_NAME);
  1403. return 0;
  1404. }
  1405. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL */
  1406. static int als_open_report_data(int open)
  1407. {
  1408. /* should queuq work to report event if is_report_input_direct=true */
  1409. return 0;
  1410. }
  1411. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL */
  1412. static int als_enable_nodata(int en)
  1413. {
  1414. int res = 0;
  1415. #ifdef CUSTOM_KERNEL_SENSORHUB
  1416. SCP_SENSOR_HUB_DATA req;
  1417. int len;
  1418. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1419. APS_LOG("APDS9930_obj als enable value = %d\n", en);
  1420. #ifdef CUSTOM_KERNEL_SENSORHUB
  1421. if (atomic_read(&APDS9930_obj->init_done)) {
  1422. req.activate_req.sensorType = ID_LIGHT;
  1423. req.activate_req.action = SENSOR_HUB_ACTIVATE;
  1424. req.activate_req.enable = en;
  1425. len = sizeof(req.activate_req);
  1426. res = SCP_sensorHub_req_send(&req, &len, 1);
  1427. } else
  1428. APS_ERR("sensor hub has not been ready!!\n");
  1429. mutex_lock(&APDS9930_mutex);
  1430. if (en)
  1431. set_bit(CMC_BIT_ALS, &APDS9930_obj->enable);
  1432. else
  1433. clear_bit(CMC_BIT_ALS, &APDS9930_obj->enable);
  1434. mutex_unlock(&APDS9930_mutex);
  1435. #else /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1436. mutex_lock(&APDS9930_mutex);
  1437. if (en)
  1438. set_bit(CMC_BIT_ALS, &APDS9930_obj->enable);
  1439. else
  1440. clear_bit(CMC_BIT_ALS, &APDS9930_obj->enable);
  1441. mutex_unlock(&APDS9930_mutex);
  1442. if (!APDS9930_obj) {
  1443. APS_ERR("APDS9930_obj is null!!\n");
  1444. return -1;
  1445. }
  1446. res = APDS9930_enable_als(APDS9930_obj->client, en);
  1447. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1448. if (res) {
  1449. APS_ERR("als_enable_nodata is failed!!\n");
  1450. return -1;
  1451. }
  1452. return 0;
  1453. }
  1454. static int als_set_delay(u64 ns)
  1455. {
  1456. return 0;
  1457. }
  1458. static int als_get_data(int *value, int *status)
  1459. {
  1460. int err = 0;
  1461. #ifdef CUSTOM_KERNEL_SENSORHUB
  1462. SCP_SENSOR_HUB_DATA req;
  1463. int len;
  1464. #else
  1465. struct APDS9930_priv *obj = NULL;
  1466. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1467. #ifdef CUSTOM_KERNEL_SENSORHUB
  1468. if (atomic_read(&APDS9930_obj->init_done)) {
  1469. req.get_data_req.sensorType = ID_LIGHT;
  1470. req.get_data_req.action = SENSOR_HUB_GET_DATA;
  1471. len = sizeof(req.get_data_req);
  1472. err = SCP_sensorHub_req_send(&req, &len, 1);
  1473. if (err)
  1474. APS_ERR("SCP_sensorHub_req_send fail!\n");
  1475. else {
  1476. *value = req.get_data_rsp.int16_Data[0];
  1477. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1478. }
  1479. if (atomic_read(&APDS9930_obj->trace) & CMC_TRC_PS_DATA)
  1480. APS_LOG("value = %d\n", *value);
  1481. else {
  1482. APS_ERR("sensor hub hat not been ready!!\n");
  1483. err = -1;
  1484. }
  1485. #else /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1486. if (!APDS9930_obj) {
  1487. APS_ERR("APDS9930_obj is null!!\n");
  1488. return -1;
  1489. }
  1490. obj = APDS9930_obj;
  1491. err = APDS9930_read_als(obj->client, &obj->als);
  1492. if (err)
  1493. err = -1;
  1494. else {
  1495. *value = APDS9930_get_als_value(obj, obj->als);
  1496. if (*value < 0)
  1497. err = -1;
  1498. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1499. }
  1500. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1501. return err;
  1502. }
  1503. /* if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL */
  1504. static int ps_open_report_data(int open)
  1505. {
  1506. /* should queuq work to report event if is_report_input_direct=true */
  1507. return 0;
  1508. }
  1509. /* if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL */
  1510. static int ps_enable_nodata(int en)
  1511. {
  1512. int res = 0;
  1513. #ifdef CUSTOM_KERNEL_SENSORHUB
  1514. SCP_SENSOR_HUB_DATA req;
  1515. int len;
  1516. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1517. APS_LOG("APDS9930_obj als enable value = %d\n", en);
  1518. #ifdef CUSTOM_KERNEL_SENSORHUB
  1519. if (atomic_read(&APDS9930_obj->init_done)) {
  1520. req.activate_req.sensorType = ID_PROXIMITY;
  1521. req.activate_req.action = SENSOR_HUB_ACTIVATE;
  1522. req.activate_req.enable = en;
  1523. len = sizeof(req.activate_req);
  1524. res = SCP_sensorHub_req_send(&req, &len, 1);
  1525. } else
  1526. APS_ERR("sensor hub has not been ready!!\n");
  1527. mutex_lock(&APDS9930_mutex);
  1528. if (en)
  1529. set_bit(CMC_BIT_PS, &APDS9930_obj->enable);
  1530. else
  1531. clear_bit(CMC_BIT_PS, &APDS9930_obj->enable);
  1532. mutex_unlock(&APDS9930_mutex);
  1533. #else /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1534. mutex_lock(&APDS9930_mutex);
  1535. if (en)
  1536. set_bit(CMC_BIT_PS, &APDS9930_obj->enable);
  1537. else
  1538. clear_bit(CMC_BIT_PS, &APDS9930_obj->enable);
  1539. mutex_unlock(&APDS9930_mutex);
  1540. if (!APDS9930_obj) {
  1541. APS_ERR("APDS9930_obj is null!!\n");
  1542. return -1;
  1543. }
  1544. res = APDS9930_enable_ps(APDS9930_obj->client, en);
  1545. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1546. if (res) {
  1547. APS_ERR("als_enable_nodata is failed!!\n");
  1548. return -1;
  1549. }
  1550. return 0;
  1551. }
  1552. static int ps_set_delay(u64 ns)
  1553. {
  1554. return 0;
  1555. }
  1556. static int ps_get_data(int *value, int *status)
  1557. {
  1558. int err = 0;
  1559. #ifdef CUSTOM_KERNEL_SENSORHUB
  1560. SCP_SENSOR_HUB_DATA req;
  1561. int len;
  1562. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1563. #ifdef CUSTOM_KERNEL_SENSORHUB
  1564. if (atomic_read(&APDS9930_obj->init_done)) {
  1565. req.get_data_req.sensorType = ID_PROXIMITY;
  1566. req.get_data_req.action = SENSOR_HUB_GET_DATA;
  1567. len = sizeof(req.get_data_req);
  1568. err = SCP_sensorHub_req_send(&req, &len, 1);
  1569. if (err) {
  1570. APS_ERR("SCP_sensorHub_req_send fail!\n");
  1571. *value = -1;
  1572. err = -1;
  1573. } else {
  1574. *value = req.get_data_rsp.int16_Data[0];
  1575. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1576. }
  1577. if (atomic_read(&APDS9930_obj->trace) & CMC_TRC_PS_DATA)
  1578. APS_LOG("value = %d\n", *value)
  1579. else {
  1580. APS_ERR("sensor hub has not been ready!!\n");
  1581. err = -1;
  1582. }
  1583. #else /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1584. if (!APDS9930_obj) {
  1585. APS_ERR("APDS9930_obj is null!!\n");
  1586. return -1;
  1587. }
  1588. err = APDS9930_read_ps(APDS9930_obj->client, &APDS9930_obj->ps);
  1589. if (err)
  1590. err = -1;
  1591. else {
  1592. *value = APDS9930_get_ps_value(APDS9930_obj, APDS9930_obj->ps);
  1593. if (*value < 0)
  1594. err = -1;
  1595. *status = SENSOR_STATUS_ACCURACY_MEDIUM;
  1596. }
  1597. #endif /* #ifdef CUSTOM_KERNEL_SENSORHUB */
  1598. return err;
  1599. }
  1600. /*----------------------------------------------------------------------------*/
  1601. static int APDS9930_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
  1602. {
  1603. struct APDS9930_priv *obj;
  1604. /*struct hwmsen_object obj_ps, obj_als;*/
  1605. struct als_control_path als_ctl = {0};
  1606. struct als_data_path als_data = {0};
  1607. struct ps_control_path ps_ctl = {0};
  1608. struct ps_data_path ps_data = {0};
  1609. int err = 0;
  1610. APS_FUN();
  1611. /* of_get_APDS9930_platform_data(&client->dev);*/
  1612. /* configure the gpio pins */
  1613. /* err = gpio_request_one(alsps_int_gpio_number, GPIOF_IN,
  1614. "alsps_int");
  1615. if (err < 0) {
  1616. APS_ERR("Unable to request gpio int_pin\n");
  1617. return -1;
  1618. }
  1619. */
  1620. obj = kzalloc(sizeof(*obj), GFP_KERNEL);
  1621. if (!(obj)) {
  1622. err = -ENOMEM;
  1623. goto exit;
  1624. }
  1625. memset(obj, 0, sizeof(*obj));
  1626. APDS9930_obj = obj;
  1627. obj->hw = hw;
  1628. APDS9930_get_addr(obj->hw, &obj->addr);
  1629. /*for interrupt work mode support -- by liaoxl.lenovo 12.08.2011 */
  1630. INIT_WORK(&obj->irq_work, APDS9930_irq_work);
  1631. obj->client = client;
  1632. i2c_set_clientdata(client, obj);
  1633. atomic_set(&obj->als_debounce, 50);
  1634. atomic_set(&obj->als_deb_on, 0);
  1635. atomic_set(&obj->als_deb_end, 0);
  1636. atomic_set(&obj->ps_debounce, 10);
  1637. atomic_set(&obj->ps_deb_on, 0);
  1638. atomic_set(&obj->ps_deb_end, 0);
  1639. atomic_set(&obj->ps_mask, 0);
  1640. atomic_set(&obj->als_suspend, 0);
  1641. atomic_set(&obj->als_cmd_val, 0xDF);
  1642. atomic_set(&obj->ps_cmd_val, 0xC1);
  1643. atomic_set(&obj->ps_thd_val_high, obj->hw->ps_threshold_high);
  1644. atomic_set(&obj->ps_thd_val_low, obj->hw->ps_threshold_low);
  1645. obj->irq_node = of_find_compatible_node(NULL, NULL, "mediatek, als-eint");
  1646. obj->enable = 0;
  1647. obj->pending_intr = 0;
  1648. obj->als_level_num = sizeof(obj->hw->als_level) / sizeof(obj->hw->als_level[0]);
  1649. obj->als_value_num = sizeof(obj->hw->als_value) / sizeof(obj->hw->als_value[0]);
  1650. /*Lenovo-sw chenlj2 add 2011-06-03,modified gain 16 to 1/5 according to actual thing */
  1651. /* (1/Gain)*(400/Tine), this value is fix after init ATIME and CONTROL register value */
  1652. obj->als_modulus = (400 * 100 * ZOOM_TIME) / (1 * 150);
  1653. /* (400)/16*2.72 here is amplify *100 / *16 */
  1654. BUG_ON(sizeof(obj->als_level) != sizeof(obj->hw->als_level));
  1655. memcpy(obj->als_level, obj->hw->als_level, sizeof(obj->als_level));
  1656. BUG_ON(sizeof(obj->als_value) != sizeof(obj->hw->als_value));
  1657. memcpy(obj->als_value, obj->hw->als_value, sizeof(obj->als_value));
  1658. atomic_set(&obj->i2c_retry, 3);
  1659. set_bit(CMC_BIT_ALS, &obj->enable);
  1660. set_bit(CMC_BIT_PS, &obj->enable);
  1661. obj->ps_cali = 0;
  1662. APDS9930_i2c_client = client;
  1663. /*if (1 == obj->hw->polling_mode_ps)
  1664. {
  1665. obj_ps.polling = 1;
  1666. } else {
  1667. obj_ps.polling = 0;
  1668. }*/
  1669. err = APDS9930_init_client(client);
  1670. if (err)
  1671. goto exit_init_failed;
  1672. APS_LOG("APDS9930_init_client() OK!\n");
  1673. err = misc_register(&APDS9930_device);
  1674. if (err) {
  1675. APS_ERR("APDS9930_device register failed\n");
  1676. goto exit_misc_device_register_failed;
  1677. }
  1678. als_ctl.is_use_common_factory = false;
  1679. ps_ctl.is_use_common_factory = false;
  1680. /* obj_ps.self = APDS9930_obj;
  1681. obj_ps.sensor_operate = APDS9930_ps_operate;
  1682. err = hwmsen_attach(ID_PROXIMITY, &obj_ps);
  1683. if (err) {
  1684. APS_ERR("attach fail = %d\n", err);
  1685. goto exit_create_attr_failed;
  1686. }
  1687. obj_als.self = APDS9930_obj;
  1688. obj_als.polling = 1;
  1689. obj_als.sensor_operate = APDS9930_als_operate;
  1690. err = hwmsen_attach(ID_LIGHT, &obj_als);
  1691. if (err) {
  1692. APS_ERR("attach fail = %d\n", err);
  1693. goto exit_create_attr_failed;
  1694. }*/
  1695. #if defined(CONFIG_HAS_EARLYSUSPEND)
  1696. obj->early_drv.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1,
  1697. obj->early_drv.suspend = APDS9930_early_suspend,
  1698. obj->early_drv.resume = APDS9930_late_resume, register_early_suspend(&obj->early_drv);
  1699. #endif
  1700. als_ctl.open_report_data = als_open_report_data;
  1701. als_ctl.enable_nodata = als_enable_nodata;
  1702. als_ctl.set_delay = als_set_delay;
  1703. als_ctl.is_report_input_direct = false;
  1704. #ifdef CUSTOM_KERNEL_SENSORHUB
  1705. als_ctl.is_support_batch = obj->hw->is_batch_supported_als;
  1706. #else
  1707. als_ctl.is_support_batch = false;
  1708. #endif
  1709. err = als_register_control_path(&als_ctl);
  1710. if (err) {
  1711. APS_ERR("register fail = %d\n", err);
  1712. goto exit_sensor_obj_attach_fail;
  1713. }
  1714. als_data.get_data = als_get_data;
  1715. als_data.vender_div = 100;
  1716. err = als_register_data_path(&als_data);
  1717. if (err) {
  1718. APS_ERR("tregister fail = %d\n", err);
  1719. goto exit_sensor_obj_attach_fail;
  1720. }
  1721. ps_ctl.open_report_data = ps_open_report_data;
  1722. ps_ctl.enable_nodata = ps_enable_nodata;
  1723. ps_ctl.set_delay = ps_set_delay;
  1724. ps_ctl.is_report_input_direct = false;
  1725. #ifdef CUSTOM_KERNEL_SENSORHUB
  1726. ps_ctl.is_support_batch = obj->hw->is_batch_supported_ps;
  1727. #else
  1728. ps_ctl.is_support_batch = false;
  1729. #endif
  1730. err = ps_register_control_path(&ps_ctl);
  1731. if (err) {
  1732. APS_ERR("register fail = %d\n", err);
  1733. goto exit_sensor_obj_attach_fail;
  1734. }
  1735. ps_data.get_data = ps_get_data;
  1736. ps_data.vender_div = 100;
  1737. err = ps_register_data_path(&ps_data);
  1738. if (err) {
  1739. APS_ERR("tregister fail = %d\n", err);
  1740. goto exit_sensor_obj_attach_fail;
  1741. }
  1742. err = batch_register_support_info(ID_LIGHT, als_ctl.is_support_batch, 1, 0);
  1743. if (err)
  1744. APS_ERR("register light batch support err = %d\n", err);
  1745. err = batch_register_support_info(ID_PROXIMITY, ps_ctl.is_support_batch, 1, 0);
  1746. if (err)
  1747. APS_ERR("register proximity batch support err = %d\n", err);
  1748. APDS9930_init_flag = 0;
  1749. APS_LOG("%s: OK\n", __func__);
  1750. return 0;
  1751. /*exit_create_attr_failed:*/
  1752. exit_sensor_obj_attach_fail:
  1753. misc_deregister(&APDS9930_device);
  1754. exit_misc_device_register_failed:
  1755. exit_init_failed:
  1756. /* i2c_detach_client(client); */
  1757. /* exit_kfree: */
  1758. kfree(obj);
  1759. exit:
  1760. /*gpio_free(alsps_int_gpio_number);*/
  1761. APDS9930_i2c_client = NULL;
  1762. APS_ERR("%s: err = %d\n", __func__, err);
  1763. APDS9930_init_flag = -1;
  1764. return err;
  1765. }
  1766. /*----------------------------------------------------------------------------*/
  1767. static int APDS9930_i2c_remove(struct i2c_client *client)
  1768. {
  1769. int err;
  1770. /*
  1771. if(err = APDS9930_delete_attr(&APDS9930_i2c_driver.driver))
  1772. {
  1773. APS_ERR("APDS9930_delete_attr fail: %d\n", err);
  1774. }
  1775. */
  1776. err = misc_deregister(&APDS9930_device);
  1777. if (err)
  1778. APS_ERR("misc_deregister fail: %d\n", err);
  1779. /*gpio_free(alsps_int_gpio_number);*/
  1780. APDS9930_i2c_client = NULL;
  1781. i2c_unregister_device(client);
  1782. kfree(i2c_get_clientdata(client));
  1783. return 0;
  1784. }
  1785. /*----------------------------------------------------------------------------*/
  1786. static int APDS9930_local_init(void)
  1787. {
  1788. APDS9930_power(hw, 1);
  1789. if (i2c_add_driver(&APDS9930_i2c_driver)) {
  1790. APS_ERR("add driver error\n");
  1791. return -1;
  1792. }
  1793. if (-1 == APDS9930_init_flag)
  1794. return -1;
  1795. return 0;
  1796. }
  1797. /*----------------------------------------------------------------------------*/
  1798. static int APDS9930_remove(void)
  1799. {
  1800. APS_FUN();
  1801. APDS9930_power(hw, 0);
  1802. i2c_del_driver(&APDS9930_i2c_driver);
  1803. return 0;
  1804. }
  1805. /*----------------------------------------------------------------------------*/
  1806. /*static int of_get_APDS9930_platform_data(struct device *dev)
  1807. {
  1808. struct device_node *node = NULL;
  1809. node = of_find_compatible_node(NULL, NULL, "mediatek,alsps");
  1810. if (node) {
  1811. alsps_int_gpio_number = of_get_named_gpio(node, "int-gpio", 0);
  1812. APS_ERR("alsps_int_gpio_number %d; \n", alsps_int_gpio_number);
  1813. }
  1814. return 0;
  1815. }*/
  1816. /*----------------------------------------------------------------------------*/
  1817. static int __init APDS9930_init(void)
  1818. {
  1819. const char *name = "mediatek,apds9930";
  1820. APS_FUN();
  1821. hw = get_alsps_dts_func(name, hw);
  1822. if (!hw)
  1823. APS_ERR("get dts info fail\n");
  1824. alsps_driver_add(&APDS9930_init_info);
  1825. return 0;
  1826. }
  1827. /*----------------------------------------------------------------------------*/
  1828. static void __exit APDS9930_exit(void)
  1829. {
  1830. APS_FUN();
  1831. }
  1832. /*----------------------------------------------------------------------------*/
  1833. module_init(APDS9930_init);
  1834. module_exit(APDS9930_exit);
  1835. /*----------------------------------------------------------------------------*/
  1836. MODULE_AUTHOR("Dexiang Liu");
  1837. MODULE_DESCRIPTION("APDS9930 driver");
  1838. MODULE_LICENSE("GPL");