tsl2772.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Device driver for monitoring ambient light intensity in (lux) and proximity
  4. * detection (prox) within the TAOS TSL2571, TSL2671, TMD2671, TSL2771, TMD2771,
  5. * TSL2572, TSL2672, TMD2672, TSL2772, and TMD2772 devices.
  6. *
  7. * Copyright (c) 2012, TAOS Corporation.
  8. * Copyright (c) 2017-2018 Brian Masney <masneyb@onstation.org>
  9. */
  10. #include <linux/delay.h>
  11. #include <linux/errno.h>
  12. #include <linux/i2c.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/mutex.h>
  17. #include <linux/slab.h>
  18. #include <linux/iio/events.h>
  19. #include <linux/iio/iio.h>
  20. #include <linux/iio/sysfs.h>
  21. #include <linux/platform_data/tsl2772.h>
  22. /* Cal defs */
  23. #define PROX_STAT_CAL 0
  24. #define PROX_STAT_SAMP 1
  25. #define MAX_SAMPLES_CAL 200
  26. /* TSL2772 Device ID */
  27. #define TRITON_ID 0x00
  28. #define SWORDFISH_ID 0x30
  29. #define HALIBUT_ID 0x20
  30. /* Lux calculation constants */
  31. #define TSL2772_LUX_CALC_OVER_FLOW 65535
  32. /*
  33. * TAOS Register definitions - Note: depending on device, some of these register
  34. * are not used and the register address is benign.
  35. */
  36. /* Register offsets */
  37. #define TSL2772_MAX_CONFIG_REG 16
  38. /* Device Registers and Masks */
  39. #define TSL2772_CNTRL 0x00
  40. #define TSL2772_ALS_TIME 0X01
  41. #define TSL2772_PRX_TIME 0x02
  42. #define TSL2772_WAIT_TIME 0x03
  43. #define TSL2772_ALS_MINTHRESHLO 0X04
  44. #define TSL2772_ALS_MINTHRESHHI 0X05
  45. #define TSL2772_ALS_MAXTHRESHLO 0X06
  46. #define TSL2772_ALS_MAXTHRESHHI 0X07
  47. #define TSL2772_PRX_MINTHRESHLO 0X08
  48. #define TSL2772_PRX_MINTHRESHHI 0X09
  49. #define TSL2772_PRX_MAXTHRESHLO 0X0A
  50. #define TSL2772_PRX_MAXTHRESHHI 0X0B
  51. #define TSL2772_PERSISTENCE 0x0C
  52. #define TSL2772_ALS_PRX_CONFIG 0x0D
  53. #define TSL2772_PRX_COUNT 0x0E
  54. #define TSL2772_GAIN 0x0F
  55. #define TSL2772_NOTUSED 0x10
  56. #define TSL2772_REVID 0x11
  57. #define TSL2772_CHIPID 0x12
  58. #define TSL2772_STATUS 0x13
  59. #define TSL2772_ALS_CHAN0LO 0x14
  60. #define TSL2772_ALS_CHAN0HI 0x15
  61. #define TSL2772_ALS_CHAN1LO 0x16
  62. #define TSL2772_ALS_CHAN1HI 0x17
  63. #define TSL2772_PRX_LO 0x18
  64. #define TSL2772_PRX_HI 0x19
  65. /* tsl2772 cmd reg masks */
  66. #define TSL2772_CMD_REG 0x80
  67. #define TSL2772_CMD_SPL_FN 0x60
  68. #define TSL2772_CMD_REPEAT_PROTO 0x00
  69. #define TSL2772_CMD_AUTOINC_PROTO 0x20
  70. #define TSL2772_CMD_PROX_INT_CLR 0X05
  71. #define TSL2772_CMD_ALS_INT_CLR 0x06
  72. #define TSL2772_CMD_PROXALS_INT_CLR 0X07
  73. /* tsl2772 cntrl reg masks */
  74. #define TSL2772_CNTL_ADC_ENBL 0x02
  75. #define TSL2772_CNTL_PWR_ON 0x01
  76. /* tsl2772 status reg masks */
  77. #define TSL2772_STA_ADC_VALID 0x01
  78. #define TSL2772_STA_PRX_VALID 0x02
  79. #define TSL2772_STA_ADC_PRX_VALID (TSL2772_STA_ADC_VALID | \
  80. TSL2772_STA_PRX_VALID)
  81. #define TSL2772_STA_ALS_INTR 0x10
  82. #define TSL2772_STA_PRX_INTR 0x20
  83. /* tsl2772 cntrl reg masks */
  84. #define TSL2772_CNTL_REG_CLEAR 0x00
  85. #define TSL2772_CNTL_PROX_INT_ENBL 0X20
  86. #define TSL2772_CNTL_ALS_INT_ENBL 0X10
  87. #define TSL2772_CNTL_WAIT_TMR_ENBL 0X08
  88. #define TSL2772_CNTL_PROX_DET_ENBL 0X04
  89. #define TSL2772_CNTL_PWRON 0x01
  90. #define TSL2772_CNTL_ALSPON_ENBL 0x03
  91. #define TSL2772_CNTL_INTALSPON_ENBL 0x13
  92. #define TSL2772_CNTL_PROXPON_ENBL 0x0F
  93. #define TSL2772_CNTL_INTPROXPON_ENBL 0x2F
  94. #define TSL2772_ALS_GAIN_TRIM_MIN 250
  95. #define TSL2772_ALS_GAIN_TRIM_MAX 4000
  96. /* Device family members */
  97. enum {
  98. tsl2571,
  99. tsl2671,
  100. tmd2671,
  101. tsl2771,
  102. tmd2771,
  103. tsl2572,
  104. tsl2672,
  105. tmd2672,
  106. tsl2772,
  107. tmd2772
  108. };
  109. enum {
  110. TSL2772_CHIP_UNKNOWN = 0,
  111. TSL2772_CHIP_WORKING = 1,
  112. TSL2772_CHIP_SUSPENDED = 2
  113. };
  114. /* Per-device data */
  115. struct tsl2772_als_info {
  116. u16 als_ch0;
  117. u16 als_ch1;
  118. u16 lux;
  119. };
  120. struct tsl2772_chip_info {
  121. int chan_table_elements;
  122. struct iio_chan_spec channel_with_events[4];
  123. struct iio_chan_spec channel_without_events[4];
  124. const struct iio_info *info;
  125. };
  126. struct tsl2772_chip {
  127. kernel_ulong_t id;
  128. struct mutex prox_mutex;
  129. struct mutex als_mutex;
  130. struct i2c_client *client;
  131. u16 prox_data;
  132. struct tsl2772_als_info als_cur_info;
  133. struct tsl2772_settings settings;
  134. struct tsl2772_platform_data *pdata;
  135. int als_gain_time_scale;
  136. int als_saturation;
  137. int tsl2772_chip_status;
  138. u8 tsl2772_config[TSL2772_MAX_CONFIG_REG];
  139. const struct tsl2772_chip_info *chip_info;
  140. const struct iio_info *info;
  141. s64 event_timestamp;
  142. /*
  143. * This structure is intentionally large to accommodate
  144. * updates via sysfs.
  145. * Sized to 9 = max 8 segments + 1 termination segment
  146. */
  147. struct tsl2772_lux tsl2772_device_lux[TSL2772_MAX_LUX_TABLE_SIZE];
  148. };
  149. /*
  150. * Different devices require different coefficents, and these numbers were
  151. * derived from the 'Lux Equation' section of the various device datasheets.
  152. * All of these coefficients assume a Glass Attenuation (GA) factor of 1.
  153. * The coefficients are multiplied by 1000 to avoid floating point operations.
  154. * The two rows in each table correspond to the Lux1 and Lux2 equations from
  155. * the datasheets.
  156. */
  157. static const struct tsl2772_lux tsl2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
  158. { 53000, 106000 },
  159. { 31800, 53000 },
  160. { 0, 0 },
  161. };
  162. static const struct tsl2772_lux tmd2x71_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
  163. { 24000, 48000 },
  164. { 14400, 24000 },
  165. { 0, 0 },
  166. };
  167. static const struct tsl2772_lux tsl2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
  168. { 60000, 112200 },
  169. { 37800, 60000 },
  170. { 0, 0 },
  171. };
  172. static const struct tsl2772_lux tmd2x72_lux_table[TSL2772_DEF_LUX_TABLE_SZ] = {
  173. { 20000, 35000 },
  174. { 12600, 20000 },
  175. { 0, 0 },
  176. };
  177. static const struct tsl2772_lux *tsl2772_default_lux_table_group[] = {
  178. [tsl2571] = tsl2x71_lux_table,
  179. [tsl2671] = tsl2x71_lux_table,
  180. [tmd2671] = tmd2x71_lux_table,
  181. [tsl2771] = tsl2x71_lux_table,
  182. [tmd2771] = tmd2x71_lux_table,
  183. [tsl2572] = tsl2x72_lux_table,
  184. [tsl2672] = tsl2x72_lux_table,
  185. [tmd2672] = tmd2x72_lux_table,
  186. [tsl2772] = tsl2x72_lux_table,
  187. [tmd2772] = tmd2x72_lux_table,
  188. };
  189. static const struct tsl2772_settings tsl2772_default_settings = {
  190. .als_time = 255, /* 2.72 / 2.73 ms */
  191. .als_gain = 0,
  192. .prox_time = 255, /* 2.72 / 2.73 ms */
  193. .prox_gain = 0,
  194. .wait_time = 255,
  195. .als_prox_config = 0,
  196. .als_gain_trim = 1000,
  197. .als_cal_target = 150,
  198. .als_persistence = 1,
  199. .als_interrupt_en = false,
  200. .als_thresh_low = 200,
  201. .als_thresh_high = 256,
  202. .prox_persistence = 1,
  203. .prox_interrupt_en = false,
  204. .prox_thres_low = 0,
  205. .prox_thres_high = 512,
  206. .prox_max_samples_cal = 30,
  207. .prox_pulse_count = 8,
  208. .prox_diode = TSL2772_DIODE1,
  209. .prox_power = TSL2772_100_mA
  210. };
  211. static const s16 tsl2772_als_gain[] = {
  212. 1,
  213. 8,
  214. 16,
  215. 120
  216. };
  217. static const s16 tsl2772_prox_gain[] = {
  218. 1,
  219. 2,
  220. 4,
  221. 8
  222. };
  223. static const int tsl2772_int_time_avail[][6] = {
  224. [tsl2571] = { 0, 2720, 0, 2720, 0, 696000 },
  225. [tsl2671] = { 0, 2720, 0, 2720, 0, 696000 },
  226. [tmd2671] = { 0, 2720, 0, 2720, 0, 696000 },
  227. [tsl2771] = { 0, 2720, 0, 2720, 0, 696000 },
  228. [tmd2771] = { 0, 2720, 0, 2720, 0, 696000 },
  229. [tsl2572] = { 0, 2730, 0, 2730, 0, 699000 },
  230. [tsl2672] = { 0, 2730, 0, 2730, 0, 699000 },
  231. [tmd2672] = { 0, 2730, 0, 2730, 0, 699000 },
  232. [tsl2772] = { 0, 2730, 0, 2730, 0, 699000 },
  233. [tmd2772] = { 0, 2730, 0, 2730, 0, 699000 },
  234. };
  235. static int tsl2772_int_calibscale_avail[] = { 1, 8, 16, 120 };
  236. static int tsl2772_prox_calibscale_avail[] = { 1, 2, 4, 8 };
  237. /* Channel variations */
  238. enum {
  239. ALS,
  240. PRX,
  241. ALSPRX,
  242. PRX2,
  243. ALSPRX2,
  244. };
  245. static const u8 device_channel_config[] = {
  246. [tsl2571] = ALS,
  247. [tsl2671] = PRX,
  248. [tmd2671] = PRX,
  249. [tsl2771] = ALSPRX,
  250. [tmd2771] = ALSPRX,
  251. [tsl2572] = ALS,
  252. [tsl2672] = PRX2,
  253. [tmd2672] = PRX2,
  254. [tsl2772] = ALSPRX2,
  255. [tmd2772] = ALSPRX2
  256. };
  257. static int tsl2772_read_status(struct tsl2772_chip *chip)
  258. {
  259. int ret;
  260. ret = i2c_smbus_read_byte_data(chip->client,
  261. TSL2772_CMD_REG | TSL2772_STATUS);
  262. if (ret < 0)
  263. dev_err(&chip->client->dev,
  264. "%s: failed to read STATUS register: %d\n", __func__,
  265. ret);
  266. return ret;
  267. }
  268. static int tsl2772_write_control_reg(struct tsl2772_chip *chip, u8 data)
  269. {
  270. int ret;
  271. ret = i2c_smbus_write_byte_data(chip->client,
  272. TSL2772_CMD_REG | TSL2772_CNTRL, data);
  273. if (ret < 0) {
  274. dev_err(&chip->client->dev,
  275. "%s: failed to write to control register %x: %d\n",
  276. __func__, data, ret);
  277. }
  278. return ret;
  279. }
  280. static int tsl2772_read_autoinc_regs(struct tsl2772_chip *chip, int lower_reg,
  281. int upper_reg)
  282. {
  283. u8 buf[2];
  284. int ret;
  285. ret = i2c_smbus_write_byte(chip->client,
  286. TSL2772_CMD_REG | TSL2772_CMD_AUTOINC_PROTO |
  287. lower_reg);
  288. if (ret < 0) {
  289. dev_err(&chip->client->dev,
  290. "%s: failed to enable auto increment protocol: %d\n",
  291. __func__, ret);
  292. return ret;
  293. }
  294. ret = i2c_smbus_read_byte_data(chip->client,
  295. TSL2772_CMD_REG | lower_reg);
  296. if (ret < 0) {
  297. dev_err(&chip->client->dev,
  298. "%s: failed to read from register %x: %d\n", __func__,
  299. lower_reg, ret);
  300. return ret;
  301. }
  302. buf[0] = ret;
  303. ret = i2c_smbus_read_byte_data(chip->client,
  304. TSL2772_CMD_REG | upper_reg);
  305. if (ret < 0) {
  306. dev_err(&chip->client->dev,
  307. "%s: failed to read from register %x: %d\n", __func__,
  308. upper_reg, ret);
  309. return ret;
  310. }
  311. buf[1] = ret;
  312. ret = i2c_smbus_write_byte(chip->client,
  313. TSL2772_CMD_REG | TSL2772_CMD_REPEAT_PROTO |
  314. lower_reg);
  315. if (ret < 0) {
  316. dev_err(&chip->client->dev,
  317. "%s: failed to enable repeated byte protocol: %d\n",
  318. __func__, ret);
  319. return ret;
  320. }
  321. return le16_to_cpup((const __le16 *)&buf[0]);
  322. }
  323. /**
  324. * tsl2772_get_lux() - Reads and calculates current lux value.
  325. * @indio_dev: pointer to IIO device
  326. *
  327. * The raw ch0 and ch1 values of the ambient light sensed in the last
  328. * integration cycle are read from the device. The raw values are multiplied
  329. * by a device-specific scale factor, and divided by the integration time and
  330. * device gain. The code supports multiple lux equations through the lux table
  331. * coefficients. A lux gain trim is applied to each lux equation, and then the
  332. * maximum lux within the interval 0..65535 is selected.
  333. */
  334. static int tsl2772_get_lux(struct iio_dev *indio_dev)
  335. {
  336. struct tsl2772_chip *chip = iio_priv(indio_dev);
  337. struct tsl2772_lux *p;
  338. int max_lux, ret;
  339. bool overflow;
  340. mutex_lock(&chip->als_mutex);
  341. if (chip->tsl2772_chip_status != TSL2772_CHIP_WORKING) {
  342. dev_err(&chip->client->dev, "%s: device is not enabled\n",
  343. __func__);
  344. ret = -EBUSY;
  345. goto out_unlock;
  346. }
  347. ret = tsl2772_read_status(chip);
  348. if (ret < 0)
  349. goto out_unlock;
  350. if (!(ret & TSL2772_STA_ADC_VALID)) {
  351. dev_err(&chip->client->dev,
  352. "%s: data not valid yet\n", __func__);
  353. ret = chip->als_cur_info.lux; /* return LAST VALUE */
  354. goto out_unlock;
  355. }
  356. ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN0LO,
  357. TSL2772_ALS_CHAN0HI);
  358. if (ret < 0)
  359. goto out_unlock;
  360. chip->als_cur_info.als_ch0 = ret;
  361. ret = tsl2772_read_autoinc_regs(chip, TSL2772_ALS_CHAN1LO,
  362. TSL2772_ALS_CHAN1HI);
  363. if (ret < 0)
  364. goto out_unlock;
  365. chip->als_cur_info.als_ch1 = ret;
  366. if (chip->als_cur_info.als_ch0 >= chip->als_saturation) {
  367. max_lux = TSL2772_LUX_CALC_OVER_FLOW;
  368. goto update_struct_with_max_lux;
  369. }
  370. if (!chip->als_cur_info.als_ch0) {
  371. /* have no data, so return LAST VALUE */
  372. ret = chip->als_cur_info.lux;
  373. goto out_unlock;
  374. }
  375. max_lux = 0;
  376. overflow = false;
  377. for (p = (struct tsl2772_lux *)chip->tsl2772_device_lux; p->ch0 != 0;
  378. p++) {
  379. int lux;
  380. lux = ((chip->als_cur_info.als_ch0 * p->ch0) -
  381. (chip->als_cur_info.als_ch1 * p->ch1)) /
  382. chip->als_gain_time_scale;
  383. /*
  384. * The als_gain_trim can have a value within the range 250..4000
  385. * and is a multiplier for the lux. A trim of 1000 makes no
  386. * changes to the lux, less than 1000 scales it down, and
  387. * greater than 1000 scales it up.
  388. */
  389. lux = (lux * chip->settings.als_gain_trim) / 1000;
  390. if (lux > TSL2772_LUX_CALC_OVER_FLOW) {
  391. overflow = true;
  392. continue;
  393. }
  394. max_lux = max(max_lux, lux);
  395. }
  396. if (overflow && max_lux == 0)
  397. max_lux = TSL2772_LUX_CALC_OVER_FLOW;
  398. update_struct_with_max_lux:
  399. chip->als_cur_info.lux = max_lux;
  400. ret = max_lux;
  401. out_unlock:
  402. mutex_unlock(&chip->als_mutex);
  403. return ret;
  404. }
  405. /**
  406. * tsl2772_get_prox() - Reads proximity data registers and updates
  407. * chip->prox_data.
  408. *
  409. * @indio_dev: pointer to IIO device
  410. */
  411. static int tsl2772_get_prox(struct iio_dev *indio_dev)
  412. {
  413. struct tsl2772_chip *chip = iio_priv(indio_dev);
  414. int ret;
  415. mutex_lock(&chip->prox_mutex);
  416. ret = tsl2772_read_status(chip);
  417. if (ret < 0)
  418. goto prox_poll_err;
  419. switch (chip->id) {
  420. case tsl2571:
  421. case tsl2671:
  422. case tmd2671:
  423. case tsl2771:
  424. case tmd2771:
  425. if (!(ret & TSL2772_STA_ADC_VALID)) {
  426. ret = -EINVAL;
  427. goto prox_poll_err;
  428. }
  429. break;
  430. case tsl2572:
  431. case tsl2672:
  432. case tmd2672:
  433. case tsl2772:
  434. case tmd2772:
  435. if (!(ret & TSL2772_STA_PRX_VALID)) {
  436. ret = -EINVAL;
  437. goto prox_poll_err;
  438. }
  439. break;
  440. }
  441. ret = tsl2772_read_autoinc_regs(chip, TSL2772_PRX_LO, TSL2772_PRX_HI);
  442. if (ret < 0)
  443. goto prox_poll_err;
  444. chip->prox_data = ret;
  445. prox_poll_err:
  446. mutex_unlock(&chip->prox_mutex);
  447. return ret;
  448. }
  449. /**
  450. * tsl2772_defaults() - Populates the device nominal operating parameters
  451. * with those provided by a 'platform' data struct or
  452. * with prefined defaults.
  453. *
  454. * @chip: pointer to device structure.
  455. */
  456. static void tsl2772_defaults(struct tsl2772_chip *chip)
  457. {
  458. /* If Operational settings defined elsewhere.. */
  459. if (chip->pdata && chip->pdata->platform_default_settings)
  460. memcpy(&chip->settings, chip->pdata->platform_default_settings,
  461. sizeof(tsl2772_default_settings));
  462. else
  463. memcpy(&chip->settings, &tsl2772_default_settings,
  464. sizeof(tsl2772_default_settings));
  465. /* Load up the proper lux table. */
  466. if (chip->pdata && chip->pdata->platform_lux_table[0].ch0 != 0)
  467. memcpy(chip->tsl2772_device_lux,
  468. chip->pdata->platform_lux_table,
  469. sizeof(chip->pdata->platform_lux_table));
  470. else
  471. memcpy(chip->tsl2772_device_lux,
  472. tsl2772_default_lux_table_group[chip->id],
  473. TSL2772_DEFAULT_TABLE_BYTES);
  474. }
  475. /**
  476. * tsl2772_als_calibrate() - Obtain single reading and calculate
  477. * the als_gain_trim.
  478. *
  479. * @indio_dev: pointer to IIO device
  480. */
  481. static int tsl2772_als_calibrate(struct iio_dev *indio_dev)
  482. {
  483. struct tsl2772_chip *chip = iio_priv(indio_dev);
  484. int ret, lux_val;
  485. ret = i2c_smbus_read_byte_data(chip->client,
  486. TSL2772_CMD_REG | TSL2772_CNTRL);
  487. if (ret < 0) {
  488. dev_err(&chip->client->dev,
  489. "%s: failed to read from the CNTRL register\n",
  490. __func__);
  491. return ret;
  492. }
  493. if ((ret & (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON))
  494. != (TSL2772_CNTL_ADC_ENBL | TSL2772_CNTL_PWR_ON)) {
  495. dev_err(&chip->client->dev,
  496. "%s: Device is not powered on and/or ADC is not enabled\n",
  497. __func__);
  498. return -EINVAL;
  499. } else if ((ret & TSL2772_STA_ADC_VALID) != TSL2772_STA_ADC_VALID) {
  500. dev_err(&chip->client->dev,
  501. "%s: The two ADC channels have not completed an integration cycle\n",
  502. __func__);
  503. return -ENODATA;
  504. }
  505. lux_val = tsl2772_get_lux(indio_dev);
  506. if (lux_val < 0) {
  507. dev_err(&chip->client->dev,
  508. "%s: failed to get lux\n", __func__);
  509. return lux_val;
  510. }
  511. if (lux_val == 0)
  512. return -ERANGE;
  513. ret = (chip->settings.als_cal_target * chip->settings.als_gain_trim) /
  514. lux_val;
  515. if (ret < TSL2772_ALS_GAIN_TRIM_MIN || ret > TSL2772_ALS_GAIN_TRIM_MAX)
  516. return -ERANGE;
  517. chip->settings.als_gain_trim = ret;
  518. return ret;
  519. }
  520. static int tsl2772_chip_on(struct iio_dev *indio_dev)
  521. {
  522. struct tsl2772_chip *chip = iio_priv(indio_dev);
  523. int ret, i, als_count, als_time_us;
  524. u8 *dev_reg, reg_val;
  525. /* Non calculated parameters */
  526. chip->tsl2772_config[TSL2772_ALS_TIME] = chip->settings.als_time;
  527. chip->tsl2772_config[TSL2772_PRX_TIME] = chip->settings.prox_time;
  528. chip->tsl2772_config[TSL2772_WAIT_TIME] = chip->settings.wait_time;
  529. chip->tsl2772_config[TSL2772_ALS_PRX_CONFIG] =
  530. chip->settings.als_prox_config;
  531. chip->tsl2772_config[TSL2772_ALS_MINTHRESHLO] =
  532. (chip->settings.als_thresh_low) & 0xFF;
  533. chip->tsl2772_config[TSL2772_ALS_MINTHRESHHI] =
  534. (chip->settings.als_thresh_low >> 8) & 0xFF;
  535. chip->tsl2772_config[TSL2772_ALS_MAXTHRESHLO] =
  536. (chip->settings.als_thresh_high) & 0xFF;
  537. chip->tsl2772_config[TSL2772_ALS_MAXTHRESHHI] =
  538. (chip->settings.als_thresh_high >> 8) & 0xFF;
  539. chip->tsl2772_config[TSL2772_PERSISTENCE] =
  540. (chip->settings.prox_persistence & 0xFF) << 4 |
  541. (chip->settings.als_persistence & 0xFF);
  542. chip->tsl2772_config[TSL2772_PRX_COUNT] =
  543. chip->settings.prox_pulse_count;
  544. chip->tsl2772_config[TSL2772_PRX_MINTHRESHLO] =
  545. (chip->settings.prox_thres_low) & 0xFF;
  546. chip->tsl2772_config[TSL2772_PRX_MINTHRESHHI] =
  547. (chip->settings.prox_thres_low >> 8) & 0xFF;
  548. chip->tsl2772_config[TSL2772_PRX_MAXTHRESHLO] =
  549. (chip->settings.prox_thres_high) & 0xFF;
  550. chip->tsl2772_config[TSL2772_PRX_MAXTHRESHHI] =
  551. (chip->settings.prox_thres_high >> 8) & 0xFF;
  552. /* and make sure we're not already on */
  553. if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
  554. /* if forcing a register update - turn off, then on */
  555. dev_info(&chip->client->dev, "device is already enabled\n");
  556. return -EINVAL;
  557. }
  558. /* Set the gain based on tsl2772_settings struct */
  559. chip->tsl2772_config[TSL2772_GAIN] =
  560. (chip->settings.als_gain & 0xFF) |
  561. ((chip->settings.prox_gain & 0xFF) << 2) |
  562. (chip->settings.prox_diode << 4) |
  563. (chip->settings.prox_power << 6);
  564. /* set chip time scaling and saturation */
  565. als_count = 256 - chip->settings.als_time;
  566. als_time_us = als_count * tsl2772_int_time_avail[chip->id][3];
  567. chip->als_saturation = als_count * 768; /* 75% of full scale */
  568. chip->als_gain_time_scale = als_time_us *
  569. tsl2772_als_gain[chip->settings.als_gain];
  570. /*
  571. * TSL2772 Specific power-on / adc enable sequence
  572. * Power on the device 1st.
  573. */
  574. ret = tsl2772_write_control_reg(chip, TSL2772_CNTL_PWR_ON);
  575. if (ret < 0)
  576. return ret;
  577. /*
  578. * Use the following shadow copy for our delay before enabling ADC.
  579. * Write all the registers.
  580. */
  581. for (i = 0, dev_reg = chip->tsl2772_config;
  582. i < TSL2772_MAX_CONFIG_REG; i++) {
  583. int reg = TSL2772_CMD_REG + i;
  584. ret = i2c_smbus_write_byte_data(chip->client, reg,
  585. *dev_reg++);
  586. if (ret < 0) {
  587. dev_err(&chip->client->dev,
  588. "%s: failed to write to register %x: %d\n",
  589. __func__, reg, ret);
  590. return ret;
  591. }
  592. }
  593. /* Power-on settling time */
  594. usleep_range(3000, 3500);
  595. reg_val = TSL2772_CNTL_PWR_ON | TSL2772_CNTL_ADC_ENBL |
  596. TSL2772_CNTL_PROX_DET_ENBL;
  597. if (chip->settings.als_interrupt_en)
  598. reg_val |= TSL2772_CNTL_ALS_INT_ENBL;
  599. if (chip->settings.prox_interrupt_en)
  600. reg_val |= TSL2772_CNTL_PROX_INT_ENBL;
  601. ret = tsl2772_write_control_reg(chip, reg_val);
  602. if (ret < 0)
  603. return ret;
  604. ret = i2c_smbus_write_byte(chip->client,
  605. TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
  606. TSL2772_CMD_PROXALS_INT_CLR);
  607. if (ret < 0) {
  608. dev_err(&chip->client->dev,
  609. "%s: failed to clear interrupt status: %d\n",
  610. __func__, ret);
  611. return ret;
  612. }
  613. chip->tsl2772_chip_status = TSL2772_CHIP_WORKING;
  614. return ret;
  615. }
  616. static int tsl2772_chip_off(struct iio_dev *indio_dev)
  617. {
  618. struct tsl2772_chip *chip = iio_priv(indio_dev);
  619. /* turn device off */
  620. chip->tsl2772_chip_status = TSL2772_CHIP_SUSPENDED;
  621. return tsl2772_write_control_reg(chip, 0x00);
  622. }
  623. static void tsl2772_chip_off_action(void *data)
  624. {
  625. struct iio_dev *indio_dev = data;
  626. tsl2772_chip_off(indio_dev);
  627. }
  628. /**
  629. * tsl2772_invoke_change - power cycle the device to implement the user
  630. * parameters
  631. * @indio_dev: pointer to IIO device
  632. *
  633. * Obtain and lock both ALS and PROX resources, determine and save device state
  634. * (On/Off), cycle device to implement updated parameter, put device back into
  635. * proper state, and unlock resource.
  636. */
  637. static int tsl2772_invoke_change(struct iio_dev *indio_dev)
  638. {
  639. struct tsl2772_chip *chip = iio_priv(indio_dev);
  640. int device_status = chip->tsl2772_chip_status;
  641. int ret;
  642. mutex_lock(&chip->als_mutex);
  643. mutex_lock(&chip->prox_mutex);
  644. if (device_status == TSL2772_CHIP_WORKING) {
  645. ret = tsl2772_chip_off(indio_dev);
  646. if (ret < 0)
  647. goto unlock;
  648. }
  649. ret = tsl2772_chip_on(indio_dev);
  650. unlock:
  651. mutex_unlock(&chip->prox_mutex);
  652. mutex_unlock(&chip->als_mutex);
  653. return ret;
  654. }
  655. static int tsl2772_prox_cal(struct iio_dev *indio_dev)
  656. {
  657. struct tsl2772_chip *chip = iio_priv(indio_dev);
  658. int prox_history[MAX_SAMPLES_CAL + 1];
  659. int i, ret, mean, max, sample_sum;
  660. if (chip->settings.prox_max_samples_cal < 1 ||
  661. chip->settings.prox_max_samples_cal > MAX_SAMPLES_CAL)
  662. return -EINVAL;
  663. for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
  664. usleep_range(15000, 17500);
  665. ret = tsl2772_get_prox(indio_dev);
  666. if (ret < 0)
  667. return ret;
  668. prox_history[i] = chip->prox_data;
  669. }
  670. sample_sum = 0;
  671. max = INT_MIN;
  672. for (i = 0; i < chip->settings.prox_max_samples_cal; i++) {
  673. sample_sum += prox_history[i];
  674. max = max(max, prox_history[i]);
  675. }
  676. mean = sample_sum / chip->settings.prox_max_samples_cal;
  677. chip->settings.prox_thres_high = (max << 1) - mean;
  678. return tsl2772_invoke_change(indio_dev);
  679. }
  680. static int tsl2772_read_avail(struct iio_dev *indio_dev,
  681. struct iio_chan_spec const *chan,
  682. const int **vals, int *type, int *length,
  683. long mask)
  684. {
  685. struct tsl2772_chip *chip = iio_priv(indio_dev);
  686. switch (mask) {
  687. case IIO_CHAN_INFO_CALIBSCALE:
  688. if (chan->type == IIO_INTENSITY) {
  689. *length = ARRAY_SIZE(tsl2772_int_calibscale_avail);
  690. *vals = tsl2772_int_calibscale_avail;
  691. } else {
  692. *length = ARRAY_SIZE(tsl2772_prox_calibscale_avail);
  693. *vals = tsl2772_prox_calibscale_avail;
  694. }
  695. *type = IIO_VAL_INT;
  696. return IIO_AVAIL_LIST;
  697. case IIO_CHAN_INFO_INT_TIME:
  698. *length = ARRAY_SIZE(tsl2772_int_time_avail[chip->id]);
  699. *vals = tsl2772_int_time_avail[chip->id];
  700. *type = IIO_VAL_INT_PLUS_MICRO;
  701. return IIO_AVAIL_RANGE;
  702. }
  703. return -EINVAL;
  704. }
  705. static ssize_t in_illuminance0_target_input_show(struct device *dev,
  706. struct device_attribute *attr,
  707. char *buf)
  708. {
  709. struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
  710. return snprintf(buf, PAGE_SIZE, "%d\n", chip->settings.als_cal_target);
  711. }
  712. static ssize_t in_illuminance0_target_input_store(struct device *dev,
  713. struct device_attribute *attr,
  714. const char *buf, size_t len)
  715. {
  716. struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  717. struct tsl2772_chip *chip = iio_priv(indio_dev);
  718. u16 value;
  719. int ret;
  720. if (kstrtou16(buf, 0, &value))
  721. return -EINVAL;
  722. chip->settings.als_cal_target = value;
  723. ret = tsl2772_invoke_change(indio_dev);
  724. if (ret < 0)
  725. return ret;
  726. return len;
  727. }
  728. static ssize_t in_illuminance0_calibrate_store(struct device *dev,
  729. struct device_attribute *attr,
  730. const char *buf, size_t len)
  731. {
  732. struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  733. bool value;
  734. int ret;
  735. if (kstrtobool(buf, &value) || !value)
  736. return -EINVAL;
  737. ret = tsl2772_als_calibrate(indio_dev);
  738. if (ret < 0)
  739. return ret;
  740. ret = tsl2772_invoke_change(indio_dev);
  741. if (ret < 0)
  742. return ret;
  743. return len;
  744. }
  745. static ssize_t in_illuminance0_lux_table_show(struct device *dev,
  746. struct device_attribute *attr,
  747. char *buf)
  748. {
  749. struct tsl2772_chip *chip = iio_priv(dev_to_iio_dev(dev));
  750. int i = 0;
  751. int offset = 0;
  752. while (i < TSL2772_MAX_LUX_TABLE_SIZE) {
  753. offset += snprintf(buf + offset, PAGE_SIZE, "%u,%u,",
  754. chip->tsl2772_device_lux[i].ch0,
  755. chip->tsl2772_device_lux[i].ch1);
  756. if (chip->tsl2772_device_lux[i].ch0 == 0) {
  757. /*
  758. * We just printed the first "0" entry.
  759. * Now get rid of the extra "," and break.
  760. */
  761. offset--;
  762. break;
  763. }
  764. i++;
  765. }
  766. offset += snprintf(buf + offset, PAGE_SIZE, "\n");
  767. return offset;
  768. }
  769. static ssize_t in_illuminance0_lux_table_store(struct device *dev,
  770. struct device_attribute *attr,
  771. const char *buf, size_t len)
  772. {
  773. struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  774. struct tsl2772_chip *chip = iio_priv(indio_dev);
  775. int value[ARRAY_SIZE(chip->tsl2772_device_lux) * 2 + 1];
  776. int n, ret;
  777. get_options(buf, ARRAY_SIZE(value), value);
  778. /*
  779. * We now have an array of ints starting at value[1], and
  780. * enumerated by value[0].
  781. * We expect each group of two ints to be one table entry,
  782. * and the last table entry is all 0.
  783. */
  784. n = value[0];
  785. if ((n % 2) || n < 4 ||
  786. n > ((ARRAY_SIZE(chip->tsl2772_device_lux) - 1) * 2))
  787. return -EINVAL;
  788. if ((value[(n - 1)] | value[n]) != 0)
  789. return -EINVAL;
  790. if (chip->tsl2772_chip_status == TSL2772_CHIP_WORKING) {
  791. ret = tsl2772_chip_off(indio_dev);
  792. if (ret < 0)
  793. return ret;
  794. }
  795. /* Zero out the table */
  796. memset(chip->tsl2772_device_lux, 0, sizeof(chip->tsl2772_device_lux));
  797. memcpy(chip->tsl2772_device_lux, &value[1], (value[0] * 4));
  798. ret = tsl2772_invoke_change(indio_dev);
  799. if (ret < 0)
  800. return ret;
  801. return len;
  802. }
  803. static ssize_t in_proximity0_calibrate_store(struct device *dev,
  804. struct device_attribute *attr,
  805. const char *buf, size_t len)
  806. {
  807. struct iio_dev *indio_dev = dev_to_iio_dev(dev);
  808. bool value;
  809. int ret;
  810. if (kstrtobool(buf, &value) || !value)
  811. return -EINVAL;
  812. ret = tsl2772_prox_cal(indio_dev);
  813. if (ret < 0)
  814. return ret;
  815. ret = tsl2772_invoke_change(indio_dev);
  816. if (ret < 0)
  817. return ret;
  818. return len;
  819. }
  820. static int tsl2772_read_interrupt_config(struct iio_dev *indio_dev,
  821. const struct iio_chan_spec *chan,
  822. enum iio_event_type type,
  823. enum iio_event_direction dir)
  824. {
  825. struct tsl2772_chip *chip = iio_priv(indio_dev);
  826. if (chan->type == IIO_INTENSITY)
  827. return chip->settings.als_interrupt_en;
  828. else
  829. return chip->settings.prox_interrupt_en;
  830. }
  831. static int tsl2772_write_interrupt_config(struct iio_dev *indio_dev,
  832. const struct iio_chan_spec *chan,
  833. enum iio_event_type type,
  834. enum iio_event_direction dir,
  835. int val)
  836. {
  837. struct tsl2772_chip *chip = iio_priv(indio_dev);
  838. if (chan->type == IIO_INTENSITY)
  839. chip->settings.als_interrupt_en = val ? true : false;
  840. else
  841. chip->settings.prox_interrupt_en = val ? true : false;
  842. return tsl2772_invoke_change(indio_dev);
  843. }
  844. static int tsl2772_write_event_value(struct iio_dev *indio_dev,
  845. const struct iio_chan_spec *chan,
  846. enum iio_event_type type,
  847. enum iio_event_direction dir,
  848. enum iio_event_info info,
  849. int val, int val2)
  850. {
  851. struct tsl2772_chip *chip = iio_priv(indio_dev);
  852. int ret = -EINVAL, count, persistence;
  853. u8 time;
  854. switch (info) {
  855. case IIO_EV_INFO_VALUE:
  856. if (chan->type == IIO_INTENSITY) {
  857. switch (dir) {
  858. case IIO_EV_DIR_RISING:
  859. chip->settings.als_thresh_high = val;
  860. ret = 0;
  861. break;
  862. case IIO_EV_DIR_FALLING:
  863. chip->settings.als_thresh_low = val;
  864. ret = 0;
  865. break;
  866. default:
  867. break;
  868. }
  869. } else {
  870. switch (dir) {
  871. case IIO_EV_DIR_RISING:
  872. chip->settings.prox_thres_high = val;
  873. ret = 0;
  874. break;
  875. case IIO_EV_DIR_FALLING:
  876. chip->settings.prox_thres_low = val;
  877. ret = 0;
  878. break;
  879. default:
  880. break;
  881. }
  882. }
  883. break;
  884. case IIO_EV_INFO_PERIOD:
  885. if (chan->type == IIO_INTENSITY)
  886. time = chip->settings.als_time;
  887. else
  888. time = chip->settings.prox_time;
  889. count = 256 - time;
  890. persistence = ((val * 1000000) + val2) /
  891. (count * tsl2772_int_time_avail[chip->id][3]);
  892. if (chan->type == IIO_INTENSITY) {
  893. /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
  894. if (persistence > 3)
  895. persistence = (persistence / 5) + 3;
  896. chip->settings.als_persistence = persistence;
  897. } else {
  898. chip->settings.prox_persistence = persistence;
  899. }
  900. ret = 0;
  901. break;
  902. default:
  903. break;
  904. }
  905. if (ret < 0)
  906. return ret;
  907. return tsl2772_invoke_change(indio_dev);
  908. }
  909. static int tsl2772_read_event_value(struct iio_dev *indio_dev,
  910. const struct iio_chan_spec *chan,
  911. enum iio_event_type type,
  912. enum iio_event_direction dir,
  913. enum iio_event_info info,
  914. int *val, int *val2)
  915. {
  916. struct tsl2772_chip *chip = iio_priv(indio_dev);
  917. int filter_delay, persistence;
  918. u8 time;
  919. switch (info) {
  920. case IIO_EV_INFO_VALUE:
  921. if (chan->type == IIO_INTENSITY) {
  922. switch (dir) {
  923. case IIO_EV_DIR_RISING:
  924. *val = chip->settings.als_thresh_high;
  925. return IIO_VAL_INT;
  926. case IIO_EV_DIR_FALLING:
  927. *val = chip->settings.als_thresh_low;
  928. return IIO_VAL_INT;
  929. default:
  930. return -EINVAL;
  931. }
  932. } else {
  933. switch (dir) {
  934. case IIO_EV_DIR_RISING:
  935. *val = chip->settings.prox_thres_high;
  936. return IIO_VAL_INT;
  937. case IIO_EV_DIR_FALLING:
  938. *val = chip->settings.prox_thres_low;
  939. return IIO_VAL_INT;
  940. default:
  941. return -EINVAL;
  942. }
  943. }
  944. break;
  945. case IIO_EV_INFO_PERIOD:
  946. if (chan->type == IIO_INTENSITY) {
  947. time = chip->settings.als_time;
  948. persistence = chip->settings.als_persistence;
  949. /* ALS filter values are 1, 2, 3, 5, 10, 15, ..., 60 */
  950. if (persistence > 3)
  951. persistence = (persistence - 3) * 5;
  952. } else {
  953. time = chip->settings.prox_time;
  954. persistence = chip->settings.prox_persistence;
  955. }
  956. filter_delay = persistence * (256 - time) *
  957. tsl2772_int_time_avail[chip->id][3];
  958. *val = filter_delay / 1000000;
  959. *val2 = filter_delay % 1000000;
  960. return IIO_VAL_INT_PLUS_MICRO;
  961. default:
  962. return -EINVAL;
  963. }
  964. }
  965. static int tsl2772_read_raw(struct iio_dev *indio_dev,
  966. struct iio_chan_spec const *chan,
  967. int *val,
  968. int *val2,
  969. long mask)
  970. {
  971. struct tsl2772_chip *chip = iio_priv(indio_dev);
  972. switch (mask) {
  973. case IIO_CHAN_INFO_PROCESSED:
  974. switch (chan->type) {
  975. case IIO_LIGHT:
  976. tsl2772_get_lux(indio_dev);
  977. *val = chip->als_cur_info.lux;
  978. return IIO_VAL_INT;
  979. default:
  980. return -EINVAL;
  981. }
  982. case IIO_CHAN_INFO_RAW:
  983. switch (chan->type) {
  984. case IIO_INTENSITY:
  985. tsl2772_get_lux(indio_dev);
  986. if (chan->channel == 0)
  987. *val = chip->als_cur_info.als_ch0;
  988. else
  989. *val = chip->als_cur_info.als_ch1;
  990. return IIO_VAL_INT;
  991. case IIO_PROXIMITY:
  992. tsl2772_get_prox(indio_dev);
  993. *val = chip->prox_data;
  994. return IIO_VAL_INT;
  995. default:
  996. return -EINVAL;
  997. }
  998. break;
  999. case IIO_CHAN_INFO_CALIBSCALE:
  1000. if (chan->type == IIO_LIGHT)
  1001. *val = tsl2772_als_gain[chip->settings.als_gain];
  1002. else
  1003. *val = tsl2772_prox_gain[chip->settings.prox_gain];
  1004. return IIO_VAL_INT;
  1005. case IIO_CHAN_INFO_CALIBBIAS:
  1006. *val = chip->settings.als_gain_trim;
  1007. return IIO_VAL_INT;
  1008. case IIO_CHAN_INFO_INT_TIME:
  1009. *val = 0;
  1010. *val2 = (256 - chip->settings.als_time) *
  1011. tsl2772_int_time_avail[chip->id][3];
  1012. return IIO_VAL_INT_PLUS_MICRO;
  1013. default:
  1014. return -EINVAL;
  1015. }
  1016. }
  1017. static int tsl2772_write_raw(struct iio_dev *indio_dev,
  1018. struct iio_chan_spec const *chan,
  1019. int val,
  1020. int val2,
  1021. long mask)
  1022. {
  1023. struct tsl2772_chip *chip = iio_priv(indio_dev);
  1024. switch (mask) {
  1025. case IIO_CHAN_INFO_CALIBSCALE:
  1026. if (chan->type == IIO_INTENSITY) {
  1027. switch (val) {
  1028. case 1:
  1029. chip->settings.als_gain = 0;
  1030. break;
  1031. case 8:
  1032. chip->settings.als_gain = 1;
  1033. break;
  1034. case 16:
  1035. chip->settings.als_gain = 2;
  1036. break;
  1037. case 120:
  1038. chip->settings.als_gain = 3;
  1039. break;
  1040. default:
  1041. return -EINVAL;
  1042. }
  1043. } else {
  1044. switch (val) {
  1045. case 1:
  1046. chip->settings.prox_gain = 0;
  1047. break;
  1048. case 2:
  1049. chip->settings.prox_gain = 1;
  1050. break;
  1051. case 4:
  1052. chip->settings.prox_gain = 2;
  1053. break;
  1054. case 8:
  1055. chip->settings.prox_gain = 3;
  1056. break;
  1057. default:
  1058. return -EINVAL;
  1059. }
  1060. }
  1061. break;
  1062. case IIO_CHAN_INFO_CALIBBIAS:
  1063. if (val < TSL2772_ALS_GAIN_TRIM_MIN ||
  1064. val > TSL2772_ALS_GAIN_TRIM_MAX)
  1065. return -EINVAL;
  1066. chip->settings.als_gain_trim = val;
  1067. break;
  1068. case IIO_CHAN_INFO_INT_TIME:
  1069. if (val != 0 || val2 < tsl2772_int_time_avail[chip->id][1] ||
  1070. val2 > tsl2772_int_time_avail[chip->id][5])
  1071. return -EINVAL;
  1072. chip->settings.als_time = 256 -
  1073. (val2 / tsl2772_int_time_avail[chip->id][3]);
  1074. break;
  1075. default:
  1076. return -EINVAL;
  1077. }
  1078. return tsl2772_invoke_change(indio_dev);
  1079. }
  1080. static DEVICE_ATTR_RW(in_illuminance0_target_input);
  1081. static DEVICE_ATTR_WO(in_illuminance0_calibrate);
  1082. static DEVICE_ATTR_WO(in_proximity0_calibrate);
  1083. static DEVICE_ATTR_RW(in_illuminance0_lux_table);
  1084. /* Use the default register values to identify the Taos device */
  1085. static int tsl2772_device_id_verif(int id, int target)
  1086. {
  1087. switch (target) {
  1088. case tsl2571:
  1089. case tsl2671:
  1090. case tsl2771:
  1091. return (id & 0xf0) == TRITON_ID;
  1092. case tmd2671:
  1093. case tmd2771:
  1094. return (id & 0xf0) == HALIBUT_ID;
  1095. case tsl2572:
  1096. case tsl2672:
  1097. case tmd2672:
  1098. case tsl2772:
  1099. case tmd2772:
  1100. return (id & 0xf0) == SWORDFISH_ID;
  1101. }
  1102. return -EINVAL;
  1103. }
  1104. static irqreturn_t tsl2772_event_handler(int irq, void *private)
  1105. {
  1106. struct iio_dev *indio_dev = private;
  1107. struct tsl2772_chip *chip = iio_priv(indio_dev);
  1108. s64 timestamp = iio_get_time_ns(indio_dev);
  1109. int ret;
  1110. ret = tsl2772_read_status(chip);
  1111. if (ret < 0)
  1112. return IRQ_HANDLED;
  1113. /* What type of interrupt do we need to process */
  1114. if (ret & TSL2772_STA_PRX_INTR) {
  1115. iio_push_event(indio_dev,
  1116. IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
  1117. 0,
  1118. IIO_EV_TYPE_THRESH,
  1119. IIO_EV_DIR_EITHER),
  1120. timestamp);
  1121. }
  1122. if (ret & TSL2772_STA_ALS_INTR) {
  1123. iio_push_event(indio_dev,
  1124. IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
  1125. 0,
  1126. IIO_EV_TYPE_THRESH,
  1127. IIO_EV_DIR_EITHER),
  1128. timestamp);
  1129. }
  1130. ret = i2c_smbus_write_byte(chip->client,
  1131. TSL2772_CMD_REG | TSL2772_CMD_SPL_FN |
  1132. TSL2772_CMD_PROXALS_INT_CLR);
  1133. if (ret < 0)
  1134. dev_err(&chip->client->dev,
  1135. "%s: failed to clear interrupt status: %d\n",
  1136. __func__, ret);
  1137. return IRQ_HANDLED;
  1138. }
  1139. static struct attribute *tsl2772_ALS_device_attrs[] = {
  1140. &dev_attr_in_illuminance0_target_input.attr,
  1141. &dev_attr_in_illuminance0_calibrate.attr,
  1142. &dev_attr_in_illuminance0_lux_table.attr,
  1143. NULL
  1144. };
  1145. static struct attribute *tsl2772_PRX_device_attrs[] = {
  1146. &dev_attr_in_proximity0_calibrate.attr,
  1147. NULL
  1148. };
  1149. static struct attribute *tsl2772_ALSPRX_device_attrs[] = {
  1150. &dev_attr_in_illuminance0_target_input.attr,
  1151. &dev_attr_in_illuminance0_calibrate.attr,
  1152. &dev_attr_in_illuminance0_lux_table.attr,
  1153. NULL
  1154. };
  1155. static struct attribute *tsl2772_PRX2_device_attrs[] = {
  1156. &dev_attr_in_proximity0_calibrate.attr,
  1157. NULL
  1158. };
  1159. static struct attribute *tsl2772_ALSPRX2_device_attrs[] = {
  1160. &dev_attr_in_illuminance0_target_input.attr,
  1161. &dev_attr_in_illuminance0_calibrate.attr,
  1162. &dev_attr_in_illuminance0_lux_table.attr,
  1163. &dev_attr_in_proximity0_calibrate.attr,
  1164. NULL
  1165. };
  1166. static const struct attribute_group tsl2772_device_attr_group_tbl[] = {
  1167. [ALS] = {
  1168. .attrs = tsl2772_ALS_device_attrs,
  1169. },
  1170. [PRX] = {
  1171. .attrs = tsl2772_PRX_device_attrs,
  1172. },
  1173. [ALSPRX] = {
  1174. .attrs = tsl2772_ALSPRX_device_attrs,
  1175. },
  1176. [PRX2] = {
  1177. .attrs = tsl2772_PRX2_device_attrs,
  1178. },
  1179. [ALSPRX2] = {
  1180. .attrs = tsl2772_ALSPRX2_device_attrs,
  1181. },
  1182. };
  1183. #define TSL2772_DEVICE_INFO(type)[type] = \
  1184. { \
  1185. .attrs = &tsl2772_device_attr_group_tbl[type], \
  1186. .read_raw = &tsl2772_read_raw, \
  1187. .read_avail = &tsl2772_read_avail, \
  1188. .write_raw = &tsl2772_write_raw, \
  1189. .read_event_value = &tsl2772_read_event_value, \
  1190. .write_event_value = &tsl2772_write_event_value, \
  1191. .read_event_config = &tsl2772_read_interrupt_config, \
  1192. .write_event_config = &tsl2772_write_interrupt_config, \
  1193. }
  1194. static const struct iio_info tsl2772_device_info[] = {
  1195. TSL2772_DEVICE_INFO(ALS),
  1196. TSL2772_DEVICE_INFO(PRX),
  1197. TSL2772_DEVICE_INFO(ALSPRX),
  1198. TSL2772_DEVICE_INFO(PRX2),
  1199. TSL2772_DEVICE_INFO(ALSPRX2),
  1200. };
  1201. static const struct iio_event_spec tsl2772_events[] = {
  1202. {
  1203. .type = IIO_EV_TYPE_THRESH,
  1204. .dir = IIO_EV_DIR_RISING,
  1205. .mask_separate = BIT(IIO_EV_INFO_VALUE),
  1206. }, {
  1207. .type = IIO_EV_TYPE_THRESH,
  1208. .dir = IIO_EV_DIR_FALLING,
  1209. .mask_separate = BIT(IIO_EV_INFO_VALUE),
  1210. }, {
  1211. .type = IIO_EV_TYPE_THRESH,
  1212. .dir = IIO_EV_DIR_EITHER,
  1213. .mask_separate = BIT(IIO_EV_INFO_PERIOD) |
  1214. BIT(IIO_EV_INFO_ENABLE),
  1215. },
  1216. };
  1217. static const struct tsl2772_chip_info tsl2772_chip_info_tbl[] = {
  1218. [ALS] = {
  1219. .channel_with_events = {
  1220. {
  1221. .type = IIO_LIGHT,
  1222. .indexed = 1,
  1223. .channel = 0,
  1224. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1225. }, {
  1226. .type = IIO_INTENSITY,
  1227. .indexed = 1,
  1228. .channel = 0,
  1229. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1230. BIT(IIO_CHAN_INFO_INT_TIME) |
  1231. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1232. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1233. .info_mask_separate_available =
  1234. BIT(IIO_CHAN_INFO_INT_TIME) |
  1235. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1236. .event_spec = tsl2772_events,
  1237. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1238. }, {
  1239. .type = IIO_INTENSITY,
  1240. .indexed = 1,
  1241. .channel = 1,
  1242. },
  1243. },
  1244. .channel_without_events = {
  1245. {
  1246. .type = IIO_LIGHT,
  1247. .indexed = 1,
  1248. .channel = 0,
  1249. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1250. }, {
  1251. .type = IIO_INTENSITY,
  1252. .indexed = 1,
  1253. .channel = 0,
  1254. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1255. BIT(IIO_CHAN_INFO_INT_TIME) |
  1256. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1257. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1258. .info_mask_separate_available =
  1259. BIT(IIO_CHAN_INFO_INT_TIME) |
  1260. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1261. }, {
  1262. .type = IIO_INTENSITY,
  1263. .indexed = 1,
  1264. .channel = 1,
  1265. },
  1266. },
  1267. .chan_table_elements = 3,
  1268. .info = &tsl2772_device_info[ALS],
  1269. },
  1270. [PRX] = {
  1271. .channel_with_events = {
  1272. {
  1273. .type = IIO_PROXIMITY,
  1274. .indexed = 1,
  1275. .channel = 0,
  1276. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1277. .event_spec = tsl2772_events,
  1278. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1279. },
  1280. },
  1281. .channel_without_events = {
  1282. {
  1283. .type = IIO_PROXIMITY,
  1284. .indexed = 1,
  1285. .channel = 0,
  1286. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1287. },
  1288. },
  1289. .chan_table_elements = 1,
  1290. .info = &tsl2772_device_info[PRX],
  1291. },
  1292. [ALSPRX] = {
  1293. .channel_with_events = {
  1294. {
  1295. .type = IIO_LIGHT,
  1296. .indexed = 1,
  1297. .channel = 0,
  1298. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1299. }, {
  1300. .type = IIO_INTENSITY,
  1301. .indexed = 1,
  1302. .channel = 0,
  1303. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1304. BIT(IIO_CHAN_INFO_INT_TIME) |
  1305. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1306. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1307. .info_mask_separate_available =
  1308. BIT(IIO_CHAN_INFO_INT_TIME) |
  1309. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1310. .event_spec = tsl2772_events,
  1311. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1312. }, {
  1313. .type = IIO_INTENSITY,
  1314. .indexed = 1,
  1315. .channel = 1,
  1316. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1317. }, {
  1318. .type = IIO_PROXIMITY,
  1319. .indexed = 1,
  1320. .channel = 0,
  1321. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1322. .event_spec = tsl2772_events,
  1323. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1324. },
  1325. },
  1326. .channel_without_events = {
  1327. {
  1328. .type = IIO_LIGHT,
  1329. .indexed = 1,
  1330. .channel = 0,
  1331. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1332. }, {
  1333. .type = IIO_INTENSITY,
  1334. .indexed = 1,
  1335. .channel = 0,
  1336. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1337. BIT(IIO_CHAN_INFO_INT_TIME) |
  1338. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1339. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1340. .info_mask_separate_available =
  1341. BIT(IIO_CHAN_INFO_INT_TIME) |
  1342. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1343. }, {
  1344. .type = IIO_INTENSITY,
  1345. .indexed = 1,
  1346. .channel = 1,
  1347. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1348. }, {
  1349. .type = IIO_PROXIMITY,
  1350. .indexed = 1,
  1351. .channel = 0,
  1352. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1353. },
  1354. },
  1355. .chan_table_elements = 4,
  1356. .info = &tsl2772_device_info[ALSPRX],
  1357. },
  1358. [PRX2] = {
  1359. .channel_with_events = {
  1360. {
  1361. .type = IIO_PROXIMITY,
  1362. .indexed = 1,
  1363. .channel = 0,
  1364. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1365. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1366. .info_mask_separate_available =
  1367. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1368. .event_spec = tsl2772_events,
  1369. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1370. },
  1371. },
  1372. .channel_without_events = {
  1373. {
  1374. .type = IIO_PROXIMITY,
  1375. .indexed = 1,
  1376. .channel = 0,
  1377. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1378. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1379. .info_mask_separate_available =
  1380. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1381. },
  1382. },
  1383. .chan_table_elements = 1,
  1384. .info = &tsl2772_device_info[PRX2],
  1385. },
  1386. [ALSPRX2] = {
  1387. .channel_with_events = {
  1388. {
  1389. .type = IIO_LIGHT,
  1390. .indexed = 1,
  1391. .channel = 0,
  1392. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1393. }, {
  1394. .type = IIO_INTENSITY,
  1395. .indexed = 1,
  1396. .channel = 0,
  1397. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1398. BIT(IIO_CHAN_INFO_INT_TIME) |
  1399. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1400. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1401. .info_mask_separate_available =
  1402. BIT(IIO_CHAN_INFO_INT_TIME) |
  1403. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1404. .event_spec = tsl2772_events,
  1405. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1406. }, {
  1407. .type = IIO_INTENSITY,
  1408. .indexed = 1,
  1409. .channel = 1,
  1410. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1411. }, {
  1412. .type = IIO_PROXIMITY,
  1413. .indexed = 1,
  1414. .channel = 0,
  1415. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1416. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1417. .info_mask_separate_available =
  1418. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1419. .event_spec = tsl2772_events,
  1420. .num_event_specs = ARRAY_SIZE(tsl2772_events),
  1421. },
  1422. },
  1423. .channel_without_events = {
  1424. {
  1425. .type = IIO_LIGHT,
  1426. .indexed = 1,
  1427. .channel = 0,
  1428. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  1429. }, {
  1430. .type = IIO_INTENSITY,
  1431. .indexed = 1,
  1432. .channel = 0,
  1433. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1434. BIT(IIO_CHAN_INFO_INT_TIME) |
  1435. BIT(IIO_CHAN_INFO_CALIBSCALE) |
  1436. BIT(IIO_CHAN_INFO_CALIBBIAS),
  1437. .info_mask_separate_available =
  1438. BIT(IIO_CHAN_INFO_INT_TIME) |
  1439. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1440. }, {
  1441. .type = IIO_INTENSITY,
  1442. .indexed = 1,
  1443. .channel = 1,
  1444. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  1445. }, {
  1446. .type = IIO_PROXIMITY,
  1447. .indexed = 1,
  1448. .channel = 0,
  1449. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  1450. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1451. .info_mask_separate_available =
  1452. BIT(IIO_CHAN_INFO_CALIBSCALE),
  1453. },
  1454. },
  1455. .chan_table_elements = 4,
  1456. .info = &tsl2772_device_info[ALSPRX2],
  1457. },
  1458. };
  1459. static int tsl2772_probe(struct i2c_client *clientp,
  1460. const struct i2c_device_id *id)
  1461. {
  1462. struct iio_dev *indio_dev;
  1463. struct tsl2772_chip *chip;
  1464. int ret;
  1465. indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
  1466. if (!indio_dev)
  1467. return -ENOMEM;
  1468. chip = iio_priv(indio_dev);
  1469. chip->client = clientp;
  1470. i2c_set_clientdata(clientp, indio_dev);
  1471. ret = i2c_smbus_read_byte_data(chip->client,
  1472. TSL2772_CMD_REG | TSL2772_CHIPID);
  1473. if (ret < 0)
  1474. return ret;
  1475. if (tsl2772_device_id_verif(ret, id->driver_data) <= 0) {
  1476. dev_info(&chip->client->dev,
  1477. "%s: i2c device found does not match expected id\n",
  1478. __func__);
  1479. return -EINVAL;
  1480. }
  1481. ret = i2c_smbus_write_byte(clientp, TSL2772_CMD_REG | TSL2772_CNTRL);
  1482. if (ret < 0) {
  1483. dev_err(&clientp->dev,
  1484. "%s: Failed to write to CMD register: %d\n",
  1485. __func__, ret);
  1486. return ret;
  1487. }
  1488. mutex_init(&chip->als_mutex);
  1489. mutex_init(&chip->prox_mutex);
  1490. chip->tsl2772_chip_status = TSL2772_CHIP_UNKNOWN;
  1491. chip->pdata = dev_get_platdata(&clientp->dev);
  1492. chip->id = id->driver_data;
  1493. chip->chip_info =
  1494. &tsl2772_chip_info_tbl[device_channel_config[id->driver_data]];
  1495. indio_dev->info = chip->chip_info->info;
  1496. indio_dev->dev.parent = &clientp->dev;
  1497. indio_dev->modes = INDIO_DIRECT_MODE;
  1498. indio_dev->name = chip->client->name;
  1499. indio_dev->num_channels = chip->chip_info->chan_table_elements;
  1500. if (clientp->irq) {
  1501. indio_dev->channels = chip->chip_info->channel_with_events;
  1502. ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
  1503. NULL,
  1504. &tsl2772_event_handler,
  1505. IRQF_TRIGGER_FALLING |
  1506. IRQF_ONESHOT,
  1507. "TSL2772_event",
  1508. indio_dev);
  1509. if (ret) {
  1510. dev_err(&clientp->dev,
  1511. "%s: irq request failed\n", __func__);
  1512. return ret;
  1513. }
  1514. } else {
  1515. indio_dev->channels = chip->chip_info->channel_without_events;
  1516. }
  1517. tsl2772_defaults(chip);
  1518. ret = tsl2772_chip_on(indio_dev);
  1519. if (ret < 0)
  1520. return ret;
  1521. ret = devm_add_action_or_reset(&clientp->dev,
  1522. tsl2772_chip_off_action,
  1523. indio_dev);
  1524. if (ret < 0)
  1525. return ret;
  1526. ret = iio_device_register(indio_dev);
  1527. if (ret) {
  1528. dev_err(&clientp->dev,
  1529. "%s: iio registration failed\n", __func__);
  1530. return ret;
  1531. }
  1532. return 0;
  1533. }
  1534. static int tsl2772_suspend(struct device *dev)
  1535. {
  1536. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  1537. return tsl2772_chip_off(indio_dev);
  1538. }
  1539. static int tsl2772_resume(struct device *dev)
  1540. {
  1541. struct iio_dev *indio_dev = dev_get_drvdata(dev);
  1542. return tsl2772_chip_on(indio_dev);
  1543. }
  1544. static int tsl2772_remove(struct i2c_client *client)
  1545. {
  1546. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  1547. iio_device_unregister(indio_dev);
  1548. return 0;
  1549. }
  1550. static const struct i2c_device_id tsl2772_idtable[] = {
  1551. { "tsl2571", tsl2571 },
  1552. { "tsl2671", tsl2671 },
  1553. { "tmd2671", tmd2671 },
  1554. { "tsl2771", tsl2771 },
  1555. { "tmd2771", tmd2771 },
  1556. { "tsl2572", tsl2572 },
  1557. { "tsl2672", tsl2672 },
  1558. { "tmd2672", tmd2672 },
  1559. { "tsl2772", tsl2772 },
  1560. { "tmd2772", tmd2772 },
  1561. {}
  1562. };
  1563. MODULE_DEVICE_TABLE(i2c, tsl2772_idtable);
  1564. static const struct of_device_id tsl2772_of_match[] = {
  1565. { .compatible = "amstaos,tsl2571" },
  1566. { .compatible = "amstaos,tsl2671" },
  1567. { .compatible = "amstaos,tmd2671" },
  1568. { .compatible = "amstaos,tsl2771" },
  1569. { .compatible = "amstaos,tmd2771" },
  1570. { .compatible = "amstaos,tsl2572" },
  1571. { .compatible = "amstaos,tsl2672" },
  1572. { .compatible = "amstaos,tmd2672" },
  1573. { .compatible = "amstaos,tsl2772" },
  1574. { .compatible = "amstaos,tmd2772" },
  1575. {}
  1576. };
  1577. MODULE_DEVICE_TABLE(of, tsl2772_of_match);
  1578. static const struct dev_pm_ops tsl2772_pm_ops = {
  1579. .suspend = tsl2772_suspend,
  1580. .resume = tsl2772_resume,
  1581. };
  1582. static struct i2c_driver tsl2772_driver = {
  1583. .driver = {
  1584. .name = "tsl2772",
  1585. .of_match_table = tsl2772_of_match,
  1586. .pm = &tsl2772_pm_ops,
  1587. },
  1588. .id_table = tsl2772_idtable,
  1589. .probe = tsl2772_probe,
  1590. .remove = tsl2772_remove,
  1591. };
  1592. module_i2c_driver(tsl2772_driver);
  1593. MODULE_AUTHOR("J. August Brenner <Jon.Brenner@ams.com>");
  1594. MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
  1595. MODULE_DESCRIPTION("TAOS tsl2772 ambient and proximity light sensor driver");
  1596. MODULE_LICENSE("GPL");