1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Samsung Electronics Co., Ltd. 4 * Author: Jacek Anaszewski <j.anaszewski@samsung.com> 5 * 6 * IIO features supported by the driver: 7 * 8 * Read-only raw channels: 9 * - illuminance_clear [lux] 10 * - illuminance_ir 11 * - proximity 12 * 13 * Triggered buffer: 14 * - illuminance_clear 15 * - illuminance_ir 16 * - proximity 17 * 18 * Events: 19 * - illuminance_clear (rising and falling) 20 * - proximity (rising and falling) 21 * - both falling and rising thresholds for the proximity events 22 * must be set to the values greater than 0. 23 * 24 * The driver supports triggered buffers for all the three 25 * channels as well as high and low threshold events for the 26 * illuminance_clear and proxmimity channels. Triggers 27 * can be enabled simultaneously with both illuminance_clear 28 * events. Proximity events cannot be enabled simultaneously 29 * with any triggers or illuminance events. Enabling/disabling 30 * one of the proximity events automatically enables/disables 31 * the other one. 32 */ 33 34 #include <linux/debugfs.h> 35 #include <linux/delay.h> 36 #include <linux/i2c.h> 37 #include <linux/interrupt.h> 38 #include <linux/irq.h> 39 #include <linux/irq_work.h> 40 #include <linux/module.h> 41 #include <linux/mod_devicetable.h> 42 #include <linux/mutex.h> 43 #include <linux/regmap.h> 44 #include <linux/regulator/consumer.h> 45 #include <linux/slab.h> 46 #include <linux/unaligned.h> 47 #include <linux/iio/buffer.h> 48 #include <linux/iio/events.h> 49 #include <linux/iio/iio.h> 50 #include <linux/iio/sysfs.h> 51 #include <linux/iio/trigger.h> 52 #include <linux/iio/trigger_consumer.h> 53 #include <linux/iio/triggered_buffer.h> 54 55 #define GP2A_I2C_NAME "gp2ap020a00f" 56 57 /* Registers */ 58 #define GP2AP020A00F_OP_REG 0x00 /* Basic operations */ 59 #define GP2AP020A00F_ALS_REG 0x01 /* ALS related settings */ 60 #define GP2AP020A00F_PS_REG 0x02 /* PS related settings */ 61 #define GP2AP020A00F_LED_REG 0x03 /* LED reg */ 62 #define GP2AP020A00F_TL_L_REG 0x04 /* ALS: Threshold low LSB */ 63 #define GP2AP020A00F_TL_H_REG 0x05 /* ALS: Threshold low MSB */ 64 #define GP2AP020A00F_TH_L_REG 0x06 /* ALS: Threshold high LSB */ 65 #define GP2AP020A00F_TH_H_REG 0x07 /* ALS: Threshold high MSB */ 66 #define GP2AP020A00F_PL_L_REG 0x08 /* PS: Threshold low LSB */ 67 #define GP2AP020A00F_PL_H_REG 0x09 /* PS: Threshold low MSB */ 68 #define GP2AP020A00F_PH_L_REG 0x0a /* PS: Threshold high LSB */ 69 #define GP2AP020A00F_PH_H_REG 0x0b /* PS: Threshold high MSB */ 70 #define GP2AP020A00F_D0_L_REG 0x0c /* ALS result: Clear/Illuminance LSB */ 71 #define GP2AP020A00F_D0_H_REG 0x0d /* ALS result: Clear/Illuminance MSB */ 72 #define GP2AP020A00F_D1_L_REG 0x0e /* ALS result: IR LSB */ 73 #define GP2AP020A00F_D1_H_REG 0x0f /* ALS result: IR LSB */ 74 #define GP2AP020A00F_D2_L_REG 0x10 /* PS result LSB */ 75 #define GP2AP020A00F_D2_H_REG 0x11 /* PS result MSB */ 76 #define GP2AP020A00F_NUM_REGS 0x12 /* Number of registers */ 77 78 /* OP_REG bits */ 79 #define GP2AP020A00F_OP3_MASK 0x80 /* Software shutdown */ 80 #define GP2AP020A00F_OP3_SHUTDOWN 0x00 81 #define GP2AP020A00F_OP3_OPERATION 0x80 82 #define GP2AP020A00F_OP2_MASK 0x40 /* Auto shutdown/Continuous mode */ 83 #define GP2AP020A00F_OP2_AUTO_SHUTDOWN 0x00 84 #define GP2AP020A00F_OP2_CONT_OPERATION 0x40 85 #define GP2AP020A00F_OP_MASK 0x30 /* Operating mode selection */ 86 #define GP2AP020A00F_OP_ALS_AND_PS 0x00 87 #define GP2AP020A00F_OP_ALS 0x10 88 #define GP2AP020A00F_OP_PS 0x20 89 #define GP2AP020A00F_OP_DEBUG 0x30 90 #define GP2AP020A00F_PROX_MASK 0x08 /* PS: detection/non-detection */ 91 #define GP2AP020A00F_PROX_NON_DETECT 0x00 92 #define GP2AP020A00F_PROX_DETECT 0x08 93 #define GP2AP020A00F_FLAG_P 0x04 /* PS: interrupt result */ 94 #define GP2AP020A00F_FLAG_A 0x02 /* ALS: interrupt result */ 95 #define GP2AP020A00F_TYPE_MASK 0x01 /* Output data type selection */ 96 #define GP2AP020A00F_TYPE_MANUAL_CALC 0x00 97 #define GP2AP020A00F_TYPE_AUTO_CALC 0x01 98 99 /* ALS_REG bits */ 100 #define GP2AP020A00F_PRST_MASK 0xc0 /* Number of measurement cycles */ 101 #define GP2AP020A00F_PRST_ONCE 0x00 102 #define GP2AP020A00F_PRST_4_CYCLES 0x40 103 #define GP2AP020A00F_PRST_8_CYCLES 0x80 104 #define GP2AP020A00F_PRST_16_CYCLES 0xc0 105 #define GP2AP020A00F_RES_A_MASK 0x38 /* ALS: Resolution */ 106 #define GP2AP020A00F_RES_A_800ms 0x00 107 #define GP2AP020A00F_RES_A_400ms 0x08 108 #define GP2AP020A00F_RES_A_200ms 0x10 109 #define GP2AP020A00F_RES_A_100ms 0x18 110 #define GP2AP020A00F_RES_A_25ms 0x20 111 #define GP2AP020A00F_RES_A_6_25ms 0x28 112 #define GP2AP020A00F_RES_A_1_56ms 0x30 113 #define GP2AP020A00F_RES_A_0_39ms 0x38 114 #define GP2AP020A00F_RANGE_A_MASK 0x07 /* ALS: Max measurable range */ 115 #define GP2AP020A00F_RANGE_A_x1 0x00 116 #define GP2AP020A00F_RANGE_A_x2 0x01 117 #define GP2AP020A00F_RANGE_A_x4 0x02 118 #define GP2AP020A00F_RANGE_A_x8 0x03 119 #define GP2AP020A00F_RANGE_A_x16 0x04 120 #define GP2AP020A00F_RANGE_A_x32 0x05 121 #define GP2AP020A00F_RANGE_A_x64 0x06 122 #define GP2AP020A00F_RANGE_A_x128 0x07 123 124 /* PS_REG bits */ 125 #define GP2AP020A00F_ALC_MASK 0x80 /* Auto light cancel */ 126 #define GP2AP020A00F_ALC_ON 0x80 127 #define GP2AP020A00F_ALC_OFF 0x00 128 #define GP2AP020A00F_INTTYPE_MASK 0x40 /* Interrupt type setting */ 129 #define GP2AP020A00F_INTTYPE_LEVEL 0x00 130 #define GP2AP020A00F_INTTYPE_PULSE 0x40 131 #define GP2AP020A00F_RES_P_MASK 0x38 /* PS: Resolution */ 132 #define GP2AP020A00F_RES_P_800ms_x2 0x00 133 #define GP2AP020A00F_RES_P_400ms_x2 0x08 134 #define GP2AP020A00F_RES_P_200ms_x2 0x10 135 #define GP2AP020A00F_RES_P_100ms_x2 0x18 136 #define GP2AP020A00F_RES_P_25ms_x2 0x20 137 #define GP2AP020A00F_RES_P_6_25ms_x2 0x28 138 #define GP2AP020A00F_RES_P_1_56ms_x2 0x30 139 #define GP2AP020A00F_RES_P_0_39ms_x2 0x38 140 #define GP2AP020A00F_RANGE_P_MASK 0x07 /* PS: Max measurable range */ 141 #define GP2AP020A00F_RANGE_P_x1 0x00 142 #define GP2AP020A00F_RANGE_P_x2 0x01 143 #define GP2AP020A00F_RANGE_P_x4 0x02 144 #define GP2AP020A00F_RANGE_P_x8 0x03 145 #define GP2AP020A00F_RANGE_P_x16 0x04 146 #define GP2AP020A00F_RANGE_P_x32 0x05 147 #define GP2AP020A00F_RANGE_P_x64 0x06 148 #define GP2AP020A00F_RANGE_P_x128 0x07 149 150 /* LED reg bits */ 151 #define GP2AP020A00F_INTVAL_MASK 0xc0 /* Intermittent operating */ 152 #define GP2AP020A00F_INTVAL_0 0x00 153 #define GP2AP020A00F_INTVAL_4 0x40 154 #define GP2AP020A00F_INTVAL_8 0x80 155 #define GP2AP020A00F_INTVAL_16 0xc0 156 #define GP2AP020A00F_IS_MASK 0x30 /* ILED drive peak current */ 157 #define GP2AP020A00F_IS_13_8mA 0x00 158 #define GP2AP020A00F_IS_27_5mA 0x10 159 #define GP2AP020A00F_IS_55mA 0x20 160 #define GP2AP020A00F_IS_110mA 0x30 161 #define GP2AP020A00F_PIN_MASK 0x0c /* INT terminal setting */ 162 #define GP2AP020A00F_PIN_ALS_OR_PS 0x00 163 #define GP2AP020A00F_PIN_ALS 0x04 164 #define GP2AP020A00F_PIN_PS 0x08 165 #define GP2AP020A00F_PIN_PS_DETECT 0x0c 166 #define GP2AP020A00F_FREQ_MASK 0x02 /* LED modulation frequency */ 167 #define GP2AP020A00F_FREQ_327_5kHz 0x00 168 #define GP2AP020A00F_FREQ_81_8kHz 0x02 169 #define GP2AP020A00F_RST 0x01 /* Software reset */ 170 171 #define GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR 0 172 #define GP2AP020A00F_SCAN_MODE_LIGHT_IR 1 173 #define GP2AP020A00F_SCAN_MODE_PROXIMITY 2 174 #define GP2AP020A00F_CHAN_TIMESTAMP 3 175 176 #define GP2AP020A00F_DATA_READY_TIMEOUT msecs_to_jiffies(1000) 177 #define GP2AP020A00F_DATA_REG(chan) (GP2AP020A00F_D0_L_REG + \ 178 (chan) * 2) 179 #define GP2AP020A00F_THRESH_REG(th_val_id) (GP2AP020A00F_TL_L_REG + \ 180 (th_val_id) * 2) 181 #define GP2AP020A00F_THRESH_VAL_ID(reg_addr) ((reg_addr - 4) / 2) 182 183 #define GP2AP020A00F_SUBTRACT_MODE 0 184 #define GP2AP020A00F_ADD_MODE 1 185 186 #define GP2AP020A00F_MAX_CHANNELS 3 187 188 enum gp2ap020a00f_opmode { 189 GP2AP020A00F_OPMODE_READ_RAW_CLEAR, 190 GP2AP020A00F_OPMODE_READ_RAW_IR, 191 GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY, 192 GP2AP020A00F_OPMODE_ALS, 193 GP2AP020A00F_OPMODE_PS, 194 GP2AP020A00F_OPMODE_ALS_AND_PS, 195 GP2AP020A00F_OPMODE_PROX_DETECT, 196 GP2AP020A00F_OPMODE_SHUTDOWN, 197 GP2AP020A00F_NUM_OPMODES, 198 }; 199 200 enum gp2ap020a00f_cmd { 201 GP2AP020A00F_CMD_READ_RAW_CLEAR, 202 GP2AP020A00F_CMD_READ_RAW_IR, 203 GP2AP020A00F_CMD_READ_RAW_PROXIMITY, 204 GP2AP020A00F_CMD_TRIGGER_CLEAR_EN, 205 GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS, 206 GP2AP020A00F_CMD_TRIGGER_IR_EN, 207 GP2AP020A00F_CMD_TRIGGER_IR_DIS, 208 GP2AP020A00F_CMD_TRIGGER_PROX_EN, 209 GP2AP020A00F_CMD_TRIGGER_PROX_DIS, 210 GP2AP020A00F_CMD_ALS_HIGH_EV_EN, 211 GP2AP020A00F_CMD_ALS_HIGH_EV_DIS, 212 GP2AP020A00F_CMD_ALS_LOW_EV_EN, 213 GP2AP020A00F_CMD_ALS_LOW_EV_DIS, 214 GP2AP020A00F_CMD_PROX_HIGH_EV_EN, 215 GP2AP020A00F_CMD_PROX_HIGH_EV_DIS, 216 GP2AP020A00F_CMD_PROX_LOW_EV_EN, 217 GP2AP020A00F_CMD_PROX_LOW_EV_DIS, 218 }; 219 220 enum gp2ap020a00f_flags { 221 GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, 222 GP2AP020A00F_FLAG_ALS_IR_TRIGGER, 223 GP2AP020A00F_FLAG_PROX_TRIGGER, 224 GP2AP020A00F_FLAG_PROX_RISING_EV, 225 GP2AP020A00F_FLAG_PROX_FALLING_EV, 226 GP2AP020A00F_FLAG_ALS_RISING_EV, 227 GP2AP020A00F_FLAG_ALS_FALLING_EV, 228 GP2AP020A00F_FLAG_LUX_MODE_HI, 229 GP2AP020A00F_FLAG_DATA_READY, 230 }; 231 232 enum gp2ap020a00f_thresh_val_id { 233 GP2AP020A00F_THRESH_TL, 234 GP2AP020A00F_THRESH_TH, 235 GP2AP020A00F_THRESH_PL, 236 GP2AP020A00F_THRESH_PH, 237 }; 238 239 struct gp2ap020a00f_data { 240 struct i2c_client *client; 241 struct mutex lock; 242 char *buffer; 243 struct regulator *vled_reg; 244 unsigned long flags; 245 enum gp2ap020a00f_opmode cur_opmode; 246 struct iio_trigger *trig; 247 struct regmap *regmap; 248 unsigned int thresh_val[4]; 249 u8 debug_reg_addr; 250 struct irq_work work; 251 wait_queue_head_t data_ready_queue; 252 }; 253 254 static const u8 gp2ap020a00f_reg_init_tab[] = { 255 [GP2AP020A00F_OP_REG] = GP2AP020A00F_OP3_SHUTDOWN, 256 [GP2AP020A00F_ALS_REG] = GP2AP020A00F_RES_A_25ms | 257 GP2AP020A00F_RANGE_A_x8, 258 [GP2AP020A00F_PS_REG] = GP2AP020A00F_ALC_ON | 259 GP2AP020A00F_RES_P_1_56ms_x2 | 260 GP2AP020A00F_RANGE_P_x4, 261 [GP2AP020A00F_LED_REG] = GP2AP020A00F_INTVAL_0 | 262 GP2AP020A00F_IS_110mA | 263 GP2AP020A00F_FREQ_327_5kHz, 264 [GP2AP020A00F_TL_L_REG] = 0, 265 [GP2AP020A00F_TL_H_REG] = 0, 266 [GP2AP020A00F_TH_L_REG] = 0, 267 [GP2AP020A00F_TH_H_REG] = 0, 268 [GP2AP020A00F_PL_L_REG] = 0, 269 [GP2AP020A00F_PL_H_REG] = 0, 270 [GP2AP020A00F_PH_L_REG] = 0, 271 [GP2AP020A00F_PH_H_REG] = 0, 272 }; 273 274 static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg) 275 { 276 switch (reg) { 277 case GP2AP020A00F_OP_REG: 278 case GP2AP020A00F_D0_L_REG: 279 case GP2AP020A00F_D0_H_REG: 280 case GP2AP020A00F_D1_L_REG: 281 case GP2AP020A00F_D1_H_REG: 282 case GP2AP020A00F_D2_L_REG: 283 case GP2AP020A00F_D2_H_REG: 284 return true; 285 default: 286 return false; 287 } 288 } 289 290 static const struct regmap_config gp2ap020a00f_regmap_config = { 291 .reg_bits = 8, 292 .val_bits = 8, 293 294 .max_register = GP2AP020A00F_D2_H_REG, 295 .cache_type = REGCACHE_RBTREE, 296 297 .volatile_reg = gp2ap020a00f_is_volatile_reg, 298 }; 299 300 static const struct gp2ap020a00f_mutable_config_regs { 301 u8 op_reg; 302 u8 als_reg; 303 u8 ps_reg; 304 u8 led_reg; 305 } opmode_regs_settings[GP2AP020A00F_NUM_OPMODES] = { 306 [GP2AP020A00F_OPMODE_READ_RAW_CLEAR] = { 307 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION 308 | GP2AP020A00F_OP3_OPERATION 309 | GP2AP020A00F_TYPE_AUTO_CALC, 310 GP2AP020A00F_PRST_ONCE, 311 GP2AP020A00F_INTTYPE_LEVEL, 312 GP2AP020A00F_PIN_ALS 313 }, 314 [GP2AP020A00F_OPMODE_READ_RAW_IR] = { 315 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION 316 | GP2AP020A00F_OP3_OPERATION 317 | GP2AP020A00F_TYPE_MANUAL_CALC, 318 GP2AP020A00F_PRST_ONCE, 319 GP2AP020A00F_INTTYPE_LEVEL, 320 GP2AP020A00F_PIN_ALS 321 }, 322 [GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY] = { 323 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION 324 | GP2AP020A00F_OP3_OPERATION 325 | GP2AP020A00F_TYPE_MANUAL_CALC, 326 GP2AP020A00F_PRST_ONCE, 327 GP2AP020A00F_INTTYPE_LEVEL, 328 GP2AP020A00F_PIN_PS 329 }, 330 [GP2AP020A00F_OPMODE_PROX_DETECT] = { 331 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION 332 | GP2AP020A00F_OP3_OPERATION 333 | GP2AP020A00F_TYPE_MANUAL_CALC, 334 GP2AP020A00F_PRST_4_CYCLES, 335 GP2AP020A00F_INTTYPE_PULSE, 336 GP2AP020A00F_PIN_PS_DETECT 337 }, 338 [GP2AP020A00F_OPMODE_ALS] = { 339 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION 340 | GP2AP020A00F_OP3_OPERATION 341 | GP2AP020A00F_TYPE_AUTO_CALC, 342 GP2AP020A00F_PRST_ONCE, 343 GP2AP020A00F_INTTYPE_LEVEL, 344 GP2AP020A00F_PIN_ALS 345 }, 346 [GP2AP020A00F_OPMODE_PS] = { 347 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION 348 | GP2AP020A00F_OP3_OPERATION 349 | GP2AP020A00F_TYPE_MANUAL_CALC, 350 GP2AP020A00F_PRST_4_CYCLES, 351 GP2AP020A00F_INTTYPE_LEVEL, 352 GP2AP020A00F_PIN_PS 353 }, 354 [GP2AP020A00F_OPMODE_ALS_AND_PS] = { 355 GP2AP020A00F_OP_ALS_AND_PS 356 | GP2AP020A00F_OP2_CONT_OPERATION 357 | GP2AP020A00F_OP3_OPERATION 358 | GP2AP020A00F_TYPE_AUTO_CALC, 359 GP2AP020A00F_PRST_4_CYCLES, 360 GP2AP020A00F_INTTYPE_LEVEL, 361 GP2AP020A00F_PIN_ALS_OR_PS 362 }, 363 [GP2AP020A00F_OPMODE_SHUTDOWN] = { GP2AP020A00F_OP3_SHUTDOWN, }, 364 }; 365 366 static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data, 367 enum gp2ap020a00f_opmode op) 368 { 369 unsigned int op_reg_val; 370 int err; 371 372 if (op != GP2AP020A00F_OPMODE_SHUTDOWN) { 373 err = regmap_read(data->regmap, GP2AP020A00F_OP_REG, 374 &op_reg_val); 375 if (err < 0) 376 return err; 377 /* 378 * Shutdown the device if the operation being executed entails 379 * mode transition. 380 */ 381 if ((opmode_regs_settings[op].op_reg & GP2AP020A00F_OP_MASK) != 382 (op_reg_val & GP2AP020A00F_OP_MASK)) { 383 /* set shutdown mode */ 384 err = regmap_update_bits(data->regmap, 385 GP2AP020A00F_OP_REG, GP2AP020A00F_OP3_MASK, 386 GP2AP020A00F_OP3_SHUTDOWN); 387 if (err < 0) 388 return err; 389 } 390 391 err = regmap_update_bits(data->regmap, GP2AP020A00F_ALS_REG, 392 GP2AP020A00F_PRST_MASK, opmode_regs_settings[op] 393 .als_reg); 394 if (err < 0) 395 return err; 396 397 err = regmap_update_bits(data->regmap, GP2AP020A00F_PS_REG, 398 GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op] 399 .ps_reg); 400 if (err < 0) 401 return err; 402 403 err = regmap_update_bits(data->regmap, GP2AP020A00F_LED_REG, 404 GP2AP020A00F_PIN_MASK, opmode_regs_settings[op] 405 .led_reg); 406 if (err < 0) 407 return err; 408 } 409 410 /* Set OP_REG and apply operation mode (power on / off) */ 411 err = regmap_update_bits(data->regmap, 412 GP2AP020A00F_OP_REG, 413 GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK | 414 GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK, 415 opmode_regs_settings[op].op_reg); 416 if (err < 0) 417 return err; 418 419 data->cur_opmode = op; 420 421 return 0; 422 } 423 424 static bool gp2ap020a00f_als_enabled(struct gp2ap020a00f_data *data) 425 { 426 return test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags) || 427 test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags) || 428 test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags) || 429 test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags); 430 } 431 432 static bool gp2ap020a00f_prox_detect_enabled(struct gp2ap020a00f_data *data) 433 { 434 return test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags) || 435 test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags); 436 } 437 438 static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data, 439 enum gp2ap020a00f_thresh_val_id th_val_id, 440 bool enable) 441 { 442 __le16 thresh_buf = 0; 443 unsigned int thresh_reg_val; 444 445 if (!enable) 446 thresh_reg_val = 0; 447 else if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags) && 448 th_val_id != GP2AP020A00F_THRESH_PL && 449 th_val_id != GP2AP020A00F_THRESH_PH) 450 /* 451 * For the high lux mode ALS threshold has to be scaled down 452 * to allow for proper comparison with the output value. 453 */ 454 thresh_reg_val = data->thresh_val[th_val_id] / 16; 455 else 456 thresh_reg_val = data->thresh_val[th_val_id] > 16000 ? 457 16000 : 458 data->thresh_val[th_val_id]; 459 460 thresh_buf = cpu_to_le16(thresh_reg_val); 461 462 return regmap_bulk_write(data->regmap, 463 GP2AP020A00F_THRESH_REG(th_val_id), 464 (u8 *)&thresh_buf, 2); 465 } 466 467 static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data, 468 enum gp2ap020a00f_opmode diff_mode, int add_sub) 469 { 470 enum gp2ap020a00f_opmode new_mode; 471 472 if (diff_mode != GP2AP020A00F_OPMODE_ALS && 473 diff_mode != GP2AP020A00F_OPMODE_PS) 474 return -EINVAL; 475 476 if (add_sub == GP2AP020A00F_ADD_MODE) { 477 if (data->cur_opmode == GP2AP020A00F_OPMODE_SHUTDOWN) 478 new_mode = diff_mode; 479 else 480 new_mode = GP2AP020A00F_OPMODE_ALS_AND_PS; 481 } else { 482 if (data->cur_opmode == GP2AP020A00F_OPMODE_ALS_AND_PS) 483 new_mode = (diff_mode == GP2AP020A00F_OPMODE_ALS) ? 484 GP2AP020A00F_OPMODE_PS : 485 GP2AP020A00F_OPMODE_ALS; 486 else 487 new_mode = GP2AP020A00F_OPMODE_SHUTDOWN; 488 } 489 490 return gp2ap020a00f_set_operation_mode(data, new_mode); 491 } 492 493 static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data, 494 enum gp2ap020a00f_cmd cmd) 495 { 496 int err = 0; 497 498 switch (cmd) { 499 case GP2AP020A00F_CMD_READ_RAW_CLEAR: 500 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN) 501 return -EBUSY; 502 err = gp2ap020a00f_set_operation_mode(data, 503 GP2AP020A00F_OPMODE_READ_RAW_CLEAR); 504 break; 505 case GP2AP020A00F_CMD_READ_RAW_IR: 506 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN) 507 return -EBUSY; 508 err = gp2ap020a00f_set_operation_mode(data, 509 GP2AP020A00F_OPMODE_READ_RAW_IR); 510 break; 511 case GP2AP020A00F_CMD_READ_RAW_PROXIMITY: 512 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN) 513 return -EBUSY; 514 err = gp2ap020a00f_set_operation_mode(data, 515 GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY); 516 break; 517 case GP2AP020A00F_CMD_TRIGGER_CLEAR_EN: 518 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT) 519 return -EBUSY; 520 if (!gp2ap020a00f_als_enabled(data)) 521 err = gp2ap020a00f_alter_opmode(data, 522 GP2AP020A00F_OPMODE_ALS, 523 GP2AP020A00F_ADD_MODE); 524 set_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags); 525 break; 526 case GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS: 527 clear_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags); 528 if (gp2ap020a00f_als_enabled(data)) 529 break; 530 err = gp2ap020a00f_alter_opmode(data, 531 GP2AP020A00F_OPMODE_ALS, 532 GP2AP020A00F_SUBTRACT_MODE); 533 break; 534 case GP2AP020A00F_CMD_TRIGGER_IR_EN: 535 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT) 536 return -EBUSY; 537 if (!gp2ap020a00f_als_enabled(data)) 538 err = gp2ap020a00f_alter_opmode(data, 539 GP2AP020A00F_OPMODE_ALS, 540 GP2AP020A00F_ADD_MODE); 541 set_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags); 542 break; 543 case GP2AP020A00F_CMD_TRIGGER_IR_DIS: 544 clear_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags); 545 if (gp2ap020a00f_als_enabled(data)) 546 break; 547 err = gp2ap020a00f_alter_opmode(data, 548 GP2AP020A00F_OPMODE_ALS, 549 GP2AP020A00F_SUBTRACT_MODE); 550 break; 551 case GP2AP020A00F_CMD_TRIGGER_PROX_EN: 552 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT) 553 return -EBUSY; 554 err = gp2ap020a00f_alter_opmode(data, 555 GP2AP020A00F_OPMODE_PS, 556 GP2AP020A00F_ADD_MODE); 557 set_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags); 558 break; 559 case GP2AP020A00F_CMD_TRIGGER_PROX_DIS: 560 clear_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags); 561 err = gp2ap020a00f_alter_opmode(data, 562 GP2AP020A00F_OPMODE_PS, 563 GP2AP020A00F_SUBTRACT_MODE); 564 break; 565 case GP2AP020A00F_CMD_ALS_HIGH_EV_EN: 566 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) 567 return 0; 568 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT) 569 return -EBUSY; 570 if (!gp2ap020a00f_als_enabled(data)) { 571 err = gp2ap020a00f_alter_opmode(data, 572 GP2AP020A00F_OPMODE_ALS, 573 GP2AP020A00F_ADD_MODE); 574 if (err < 0) 575 return err; 576 } 577 set_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags); 578 err = gp2ap020a00f_write_event_threshold(data, 579 GP2AP020A00F_THRESH_TH, true); 580 break; 581 case GP2AP020A00F_CMD_ALS_HIGH_EV_DIS: 582 if (!test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) 583 return 0; 584 clear_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags); 585 if (!gp2ap020a00f_als_enabled(data)) { 586 err = gp2ap020a00f_alter_opmode(data, 587 GP2AP020A00F_OPMODE_ALS, 588 GP2AP020A00F_SUBTRACT_MODE); 589 if (err < 0) 590 return err; 591 } 592 err = gp2ap020a00f_write_event_threshold(data, 593 GP2AP020A00F_THRESH_TH, false); 594 break; 595 case GP2AP020A00F_CMD_ALS_LOW_EV_EN: 596 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) 597 return 0; 598 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT) 599 return -EBUSY; 600 if (!gp2ap020a00f_als_enabled(data)) { 601 err = gp2ap020a00f_alter_opmode(data, 602 GP2AP020A00F_OPMODE_ALS, 603 GP2AP020A00F_ADD_MODE); 604 if (err < 0) 605 return err; 606 } 607 set_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags); 608 err = gp2ap020a00f_write_event_threshold(data, 609 GP2AP020A00F_THRESH_TL, true); 610 break; 611 case GP2AP020A00F_CMD_ALS_LOW_EV_DIS: 612 if (!test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) 613 return 0; 614 clear_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags); 615 if (!gp2ap020a00f_als_enabled(data)) { 616 err = gp2ap020a00f_alter_opmode(data, 617 GP2AP020A00F_OPMODE_ALS, 618 GP2AP020A00F_SUBTRACT_MODE); 619 if (err < 0) 620 return err; 621 } 622 err = gp2ap020a00f_write_event_threshold(data, 623 GP2AP020A00F_THRESH_TL, false); 624 break; 625 case GP2AP020A00F_CMD_PROX_HIGH_EV_EN: 626 if (test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags)) 627 return 0; 628 if (gp2ap020a00f_als_enabled(data) || 629 data->cur_opmode == GP2AP020A00F_OPMODE_PS) 630 return -EBUSY; 631 if (!gp2ap020a00f_prox_detect_enabled(data)) { 632 err = gp2ap020a00f_set_operation_mode(data, 633 GP2AP020A00F_OPMODE_PROX_DETECT); 634 if (err < 0) 635 return err; 636 } 637 set_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags); 638 err = gp2ap020a00f_write_event_threshold(data, 639 GP2AP020A00F_THRESH_PH, true); 640 break; 641 case GP2AP020A00F_CMD_PROX_HIGH_EV_DIS: 642 if (!test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags)) 643 return 0; 644 clear_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags); 645 err = gp2ap020a00f_set_operation_mode(data, 646 GP2AP020A00F_OPMODE_SHUTDOWN); 647 if (err < 0) 648 return err; 649 err = gp2ap020a00f_write_event_threshold(data, 650 GP2AP020A00F_THRESH_PH, false); 651 break; 652 case GP2AP020A00F_CMD_PROX_LOW_EV_EN: 653 if (test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags)) 654 return 0; 655 if (gp2ap020a00f_als_enabled(data) || 656 data->cur_opmode == GP2AP020A00F_OPMODE_PS) 657 return -EBUSY; 658 if (!gp2ap020a00f_prox_detect_enabled(data)) { 659 err = gp2ap020a00f_set_operation_mode(data, 660 GP2AP020A00F_OPMODE_PROX_DETECT); 661 if (err < 0) 662 return err; 663 } 664 set_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags); 665 err = gp2ap020a00f_write_event_threshold(data, 666 GP2AP020A00F_THRESH_PL, true); 667 break; 668 case GP2AP020A00F_CMD_PROX_LOW_EV_DIS: 669 if (!test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags)) 670 return 0; 671 clear_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags); 672 err = gp2ap020a00f_set_operation_mode(data, 673 GP2AP020A00F_OPMODE_SHUTDOWN); 674 if (err < 0) 675 return err; 676 err = gp2ap020a00f_write_event_threshold(data, 677 GP2AP020A00F_THRESH_PL, false); 678 break; 679 } 680 681 return err; 682 } 683 684 static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data) 685 { 686 int ret; 687 688 ret = wait_event_timeout(data->data_ready_queue, 689 test_bit(GP2AP020A00F_FLAG_DATA_READY, 690 &data->flags), 691 GP2AP020A00F_DATA_READY_TIMEOUT); 692 clear_bit(GP2AP020A00F_FLAG_DATA_READY, &data->flags); 693 694 return ret > 0 ? 0 : -ETIME; 695 } 696 697 static int gp2ap020a00f_read_output(struct gp2ap020a00f_data *data, 698 unsigned int output_reg, int *val) 699 { 700 u8 reg_buf[2]; 701 int err; 702 703 err = wait_conversion_complete_irq(data); 704 if (err < 0) 705 dev_dbg(&data->client->dev, "data ready timeout\n"); 706 707 err = regmap_bulk_read(data->regmap, output_reg, reg_buf, 2); 708 if (err < 0) 709 return err; 710 711 *val = le16_to_cpup((__le16 *)reg_buf); 712 713 return err; 714 } 715 716 static bool gp2ap020a00f_adjust_lux_mode(struct gp2ap020a00f_data *data, 717 int output_val) 718 { 719 u8 new_range = 0xff; 720 int err; 721 722 if (!test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) { 723 if (output_val > 16000) { 724 set_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags); 725 new_range = GP2AP020A00F_RANGE_A_x128; 726 } 727 } else { 728 if (output_val < 1000) { 729 clear_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags); 730 new_range = GP2AP020A00F_RANGE_A_x8; 731 } 732 } 733 734 if (new_range != 0xff) { 735 /* Clear als threshold registers to avoid spurious 736 * events caused by lux mode transition. 737 */ 738 err = gp2ap020a00f_write_event_threshold(data, 739 GP2AP020A00F_THRESH_TH, false); 740 if (err < 0) { 741 dev_err(&data->client->dev, 742 "Clearing als threshold register failed.\n"); 743 return false; 744 } 745 746 err = gp2ap020a00f_write_event_threshold(data, 747 GP2AP020A00F_THRESH_TL, false); 748 if (err < 0) { 749 dev_err(&data->client->dev, 750 "Clearing als threshold register failed.\n"); 751 return false; 752 } 753 754 /* Change lux mode */ 755 err = regmap_update_bits(data->regmap, 756 GP2AP020A00F_OP_REG, 757 GP2AP020A00F_OP3_MASK, 758 GP2AP020A00F_OP3_SHUTDOWN); 759 760 if (err < 0) { 761 dev_err(&data->client->dev, 762 "Shutting down the device failed.\n"); 763 return false; 764 } 765 766 err = regmap_update_bits(data->regmap, 767 GP2AP020A00F_ALS_REG, 768 GP2AP020A00F_RANGE_A_MASK, 769 new_range); 770 771 if (err < 0) { 772 dev_err(&data->client->dev, 773 "Adjusting device lux mode failed.\n"); 774 return false; 775 } 776 777 err = regmap_update_bits(data->regmap, 778 GP2AP020A00F_OP_REG, 779 GP2AP020A00F_OP3_MASK, 780 GP2AP020A00F_OP3_OPERATION); 781 782 if (err < 0) { 783 dev_err(&data->client->dev, 784 "Powering up the device failed.\n"); 785 return false; 786 } 787 788 /* Adjust als threshold register values to the new lux mode */ 789 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) { 790 err = gp2ap020a00f_write_event_threshold(data, 791 GP2AP020A00F_THRESH_TH, true); 792 if (err < 0) { 793 dev_err(&data->client->dev, 794 "Adjusting als threshold value failed.\n"); 795 return false; 796 } 797 } 798 799 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) { 800 err = gp2ap020a00f_write_event_threshold(data, 801 GP2AP020A00F_THRESH_TL, true); 802 if (err < 0) { 803 dev_err(&data->client->dev, 804 "Adjusting als threshold value failed.\n"); 805 return false; 806 } 807 } 808 809 return true; 810 } 811 812 return false; 813 } 814 815 static void gp2ap020a00f_output_to_lux(struct gp2ap020a00f_data *data, 816 int *output_val) 817 { 818 if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) 819 *output_val *= 16; 820 } 821 822 static void gp2ap020a00f_iio_trigger_work(struct irq_work *work) 823 { 824 struct gp2ap020a00f_data *data = 825 container_of(work, struct gp2ap020a00f_data, work); 826 827 iio_trigger_poll(data->trig); 828 } 829 830 static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data) 831 { 832 struct iio_dev *indio_dev = data; 833 struct gp2ap020a00f_data *priv = iio_priv(indio_dev); 834 unsigned int op_reg_val; 835 int ret; 836 837 /* Read interrupt flags */ 838 ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, &op_reg_val); 839 if (ret < 0) 840 return IRQ_HANDLED; 841 842 if (gp2ap020a00f_prox_detect_enabled(priv)) { 843 if (op_reg_val & GP2AP020A00F_PROX_DETECT) { 844 iio_push_event(indio_dev, 845 IIO_UNMOD_EVENT_CODE( 846 IIO_PROXIMITY, 847 GP2AP020A00F_SCAN_MODE_PROXIMITY, 848 IIO_EV_TYPE_ROC, 849 IIO_EV_DIR_RISING), 850 iio_get_time_ns(indio_dev)); 851 } else { 852 iio_push_event(indio_dev, 853 IIO_UNMOD_EVENT_CODE( 854 IIO_PROXIMITY, 855 GP2AP020A00F_SCAN_MODE_PROXIMITY, 856 IIO_EV_TYPE_ROC, 857 IIO_EV_DIR_FALLING), 858 iio_get_time_ns(indio_dev)); 859 } 860 } 861 862 return IRQ_HANDLED; 863 } 864 865 static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data) 866 { 867 struct iio_dev *indio_dev = data; 868 struct gp2ap020a00f_data *priv = iio_priv(indio_dev); 869 u8 op_reg_flags, d0_reg_buf[2]; 870 unsigned int output_val, op_reg_val; 871 int thresh_val_id, ret; 872 873 /* Read interrupt flags */ 874 ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, 875 &op_reg_val); 876 if (ret < 0) 877 goto done; 878 879 op_reg_flags = op_reg_val & (GP2AP020A00F_FLAG_A | GP2AP020A00F_FLAG_P 880 | GP2AP020A00F_PROX_DETECT); 881 882 op_reg_val &= (~GP2AP020A00F_FLAG_A & ~GP2AP020A00F_FLAG_P 883 & ~GP2AP020A00F_PROX_DETECT); 884 885 /* Clear interrupt flags (if not in INTTYPE_PULSE mode) */ 886 if (priv->cur_opmode != GP2AP020A00F_OPMODE_PROX_DETECT) { 887 ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG, 888 op_reg_val); 889 if (ret < 0) 890 goto done; 891 } 892 893 if (op_reg_flags & GP2AP020A00F_FLAG_A) { 894 /* Check D0 register to assess if the lux mode 895 * transition is required. 896 */ 897 ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_D0_L_REG, 898 d0_reg_buf, 2); 899 if (ret < 0) 900 goto done; 901 902 output_val = le16_to_cpup((__le16 *)d0_reg_buf); 903 904 if (gp2ap020a00f_adjust_lux_mode(priv, output_val)) 905 goto done; 906 907 gp2ap020a00f_output_to_lux(priv, &output_val); 908 909 /* 910 * We need to check output value to distinguish 911 * between high and low ambient light threshold event. 912 */ 913 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &priv->flags)) { 914 thresh_val_id = 915 GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TH_L_REG); 916 if (output_val > priv->thresh_val[thresh_val_id]) 917 iio_push_event(indio_dev, 918 IIO_MOD_EVENT_CODE( 919 IIO_LIGHT, 920 GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, 921 IIO_MOD_LIGHT_CLEAR, 922 IIO_EV_TYPE_THRESH, 923 IIO_EV_DIR_RISING), 924 iio_get_time_ns(indio_dev)); 925 } 926 927 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &priv->flags)) { 928 thresh_val_id = 929 GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TL_L_REG); 930 if (output_val < priv->thresh_val[thresh_val_id]) 931 iio_push_event(indio_dev, 932 IIO_MOD_EVENT_CODE( 933 IIO_LIGHT, 934 GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, 935 IIO_MOD_LIGHT_CLEAR, 936 IIO_EV_TYPE_THRESH, 937 IIO_EV_DIR_FALLING), 938 iio_get_time_ns(indio_dev)); 939 } 940 } 941 942 if (priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_CLEAR || 943 priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_IR || 944 priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY) { 945 set_bit(GP2AP020A00F_FLAG_DATA_READY, &priv->flags); 946 wake_up(&priv->data_ready_queue); 947 goto done; 948 } 949 950 if (test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &priv->flags) || 951 test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &priv->flags) || 952 test_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &priv->flags)) 953 /* This fires off the trigger. */ 954 irq_work_queue(&priv->work); 955 956 done: 957 return IRQ_HANDLED; 958 } 959 960 static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data) 961 { 962 struct iio_poll_func *pf = data; 963 struct iio_dev *indio_dev = pf->indio_dev; 964 struct gp2ap020a00f_data *priv = iio_priv(indio_dev); 965 size_t d_size = 0; 966 int i, out_val, ret; 967 968 iio_for_each_active_channel(indio_dev, i) { 969 ret = regmap_bulk_read(priv->regmap, 970 GP2AP020A00F_DATA_REG(i), 971 &priv->buffer[d_size], 2); 972 if (ret < 0) 973 goto done; 974 975 if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR || 976 i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) { 977 out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]); 978 gp2ap020a00f_output_to_lux(priv, &out_val); 979 980 put_unaligned_le32(out_val, &priv->buffer[d_size]); 981 d_size += 4; 982 } else { 983 d_size += 2; 984 } 985 } 986 987 iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer, 988 pf->timestamp); 989 done: 990 iio_trigger_notify_done(indio_dev->trig); 991 992 return IRQ_HANDLED; 993 } 994 995 static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan, 996 enum iio_event_direction event_dir) 997 { 998 switch (chan->type) { 999 case IIO_PROXIMITY: 1000 if (event_dir == IIO_EV_DIR_RISING) 1001 return GP2AP020A00F_PH_L_REG; 1002 else 1003 return GP2AP020A00F_PL_L_REG; 1004 case IIO_LIGHT: 1005 if (event_dir == IIO_EV_DIR_RISING) 1006 return GP2AP020A00F_TH_L_REG; 1007 else 1008 return GP2AP020A00F_TL_L_REG; 1009 default: 1010 break; 1011 } 1012 1013 return -EINVAL; 1014 } 1015 1016 static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev, 1017 const struct iio_chan_spec *chan, 1018 enum iio_event_type type, 1019 enum iio_event_direction dir, 1020 enum iio_event_info info, 1021 int val, int val2) 1022 { 1023 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1024 bool event_en = false; 1025 u8 thresh_val_id; 1026 u8 thresh_reg_l; 1027 int err = 0; 1028 1029 mutex_lock(&data->lock); 1030 1031 thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); 1032 thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l); 1033 1034 if (thresh_val_id > GP2AP020A00F_THRESH_PH) { 1035 err = -EINVAL; 1036 goto error_unlock; 1037 } 1038 1039 switch (thresh_reg_l) { 1040 case GP2AP020A00F_TH_L_REG: 1041 event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, 1042 &data->flags); 1043 break; 1044 case GP2AP020A00F_TL_L_REG: 1045 event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, 1046 &data->flags); 1047 break; 1048 case GP2AP020A00F_PH_L_REG: 1049 if (val == 0) { 1050 err = -EINVAL; 1051 goto error_unlock; 1052 } 1053 event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, 1054 &data->flags); 1055 break; 1056 case GP2AP020A00F_PL_L_REG: 1057 if (val == 0) { 1058 err = -EINVAL; 1059 goto error_unlock; 1060 } 1061 event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, 1062 &data->flags); 1063 break; 1064 } 1065 1066 data->thresh_val[thresh_val_id] = val; 1067 err = gp2ap020a00f_write_event_threshold(data, thresh_val_id, 1068 event_en); 1069 error_unlock: 1070 mutex_unlock(&data->lock); 1071 1072 return err; 1073 } 1074 1075 static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev, 1076 const struct iio_chan_spec *chan, 1077 enum iio_event_type type, 1078 enum iio_event_direction dir, 1079 enum iio_event_info info, 1080 int *val, int *val2) 1081 { 1082 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1083 u8 thresh_reg_l; 1084 int err = IIO_VAL_INT; 1085 1086 mutex_lock(&data->lock); 1087 1088 thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); 1089 1090 if (thresh_reg_l > GP2AP020A00F_PH_L_REG) { 1091 err = -EINVAL; 1092 goto error_unlock; 1093 } 1094 1095 *val = data->thresh_val[GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l)]; 1096 1097 error_unlock: 1098 mutex_unlock(&data->lock); 1099 1100 return err; 1101 } 1102 1103 static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev, 1104 int state) 1105 { 1106 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1107 enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev; 1108 int err; 1109 1110 cmd_high_ev = state ? GP2AP020A00F_CMD_PROX_HIGH_EV_EN : 1111 GP2AP020A00F_CMD_PROX_HIGH_EV_DIS; 1112 cmd_low_ev = state ? GP2AP020A00F_CMD_PROX_LOW_EV_EN : 1113 GP2AP020A00F_CMD_PROX_LOW_EV_DIS; 1114 1115 /* 1116 * In order to enable proximity detection feature in the device 1117 * both high and low threshold registers have to be written 1118 * with different values, greater than zero. 1119 */ 1120 if (state) { 1121 if (data->thresh_val[GP2AP020A00F_THRESH_PL] == 0) 1122 return -EINVAL; 1123 1124 if (data->thresh_val[GP2AP020A00F_THRESH_PH] == 0) 1125 return -EINVAL; 1126 } 1127 1128 err = gp2ap020a00f_exec_cmd(data, cmd_high_ev); 1129 if (err < 0) 1130 return err; 1131 1132 err = gp2ap020a00f_exec_cmd(data, cmd_low_ev); 1133 if (err < 0) 1134 return err; 1135 1136 free_irq(data->client->irq, indio_dev); 1137 1138 if (state) 1139 err = request_threaded_irq(data->client->irq, NULL, 1140 &gp2ap020a00f_prox_sensing_handler, 1141 IRQF_TRIGGER_RISING | 1142 IRQF_TRIGGER_FALLING | 1143 IRQF_ONESHOT, 1144 "gp2ap020a00f_prox_sensing", 1145 indio_dev); 1146 else { 1147 err = request_threaded_irq(data->client->irq, NULL, 1148 &gp2ap020a00f_thresh_event_handler, 1149 IRQF_TRIGGER_FALLING | 1150 IRQF_ONESHOT, 1151 "gp2ap020a00f_thresh_event", 1152 indio_dev); 1153 } 1154 1155 return err; 1156 } 1157 1158 static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, 1159 const struct iio_chan_spec *chan, 1160 enum iio_event_type type, 1161 enum iio_event_direction dir, 1162 int state) 1163 { 1164 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1165 enum gp2ap020a00f_cmd cmd; 1166 int err; 1167 1168 mutex_lock(&data->lock); 1169 1170 switch (chan->type) { 1171 case IIO_PROXIMITY: 1172 err = gp2ap020a00f_write_prox_event_config(indio_dev, state); 1173 break; 1174 case IIO_LIGHT: 1175 if (dir == IIO_EV_DIR_RISING) { 1176 cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN : 1177 GP2AP020A00F_CMD_ALS_HIGH_EV_DIS; 1178 err = gp2ap020a00f_exec_cmd(data, cmd); 1179 } else { 1180 cmd = state ? GP2AP020A00F_CMD_ALS_LOW_EV_EN : 1181 GP2AP020A00F_CMD_ALS_LOW_EV_DIS; 1182 err = gp2ap020a00f_exec_cmd(data, cmd); 1183 } 1184 break; 1185 default: 1186 err = -EINVAL; 1187 } 1188 1189 mutex_unlock(&data->lock); 1190 1191 return err; 1192 } 1193 1194 static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev, 1195 const struct iio_chan_spec *chan, 1196 enum iio_event_type type, 1197 enum iio_event_direction dir) 1198 { 1199 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1200 int event_en = 0; 1201 1202 mutex_lock(&data->lock); 1203 1204 switch (chan->type) { 1205 case IIO_PROXIMITY: 1206 if (dir == IIO_EV_DIR_RISING) 1207 event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, 1208 &data->flags); 1209 else 1210 event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, 1211 &data->flags); 1212 break; 1213 case IIO_LIGHT: 1214 if (dir == IIO_EV_DIR_RISING) 1215 event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, 1216 &data->flags); 1217 else 1218 event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, 1219 &data->flags); 1220 break; 1221 default: 1222 event_en = -EINVAL; 1223 break; 1224 } 1225 1226 mutex_unlock(&data->lock); 1227 1228 return event_en; 1229 } 1230 1231 static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data, 1232 struct iio_chan_spec const *chan, int *val) 1233 { 1234 enum gp2ap020a00f_cmd cmd; 1235 int err; 1236 1237 switch (chan->scan_index) { 1238 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1239 cmd = GP2AP020A00F_CMD_READ_RAW_CLEAR; 1240 break; 1241 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1242 cmd = GP2AP020A00F_CMD_READ_RAW_IR; 1243 break; 1244 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1245 cmd = GP2AP020A00F_CMD_READ_RAW_PROXIMITY; 1246 break; 1247 default: 1248 return -EINVAL; 1249 } 1250 1251 err = gp2ap020a00f_exec_cmd(data, cmd); 1252 if (err < 0) { 1253 dev_err(&data->client->dev, 1254 "gp2ap020a00f_exec_cmd failed\n"); 1255 goto error_ret; 1256 } 1257 1258 err = gp2ap020a00f_read_output(data, chan->address, val); 1259 if (err < 0) 1260 dev_err(&data->client->dev, 1261 "gp2ap020a00f_read_output failed\n"); 1262 1263 err = gp2ap020a00f_set_operation_mode(data, 1264 GP2AP020A00F_OPMODE_SHUTDOWN); 1265 if (err < 0) 1266 dev_err(&data->client->dev, 1267 "Failed to shut down the device.\n"); 1268 1269 if (cmd == GP2AP020A00F_CMD_READ_RAW_CLEAR || 1270 cmd == GP2AP020A00F_CMD_READ_RAW_IR) 1271 gp2ap020a00f_output_to_lux(data, val); 1272 1273 error_ret: 1274 return err; 1275 } 1276 1277 static int gp2ap020a00f_read_raw(struct iio_dev *indio_dev, 1278 struct iio_chan_spec const *chan, 1279 int *val, int *val2, 1280 long mask) 1281 { 1282 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1283 int err = -EINVAL; 1284 1285 if (mask == IIO_CHAN_INFO_RAW) { 1286 err = iio_device_claim_direct_mode(indio_dev); 1287 if (err) 1288 return err; 1289 1290 err = gp2ap020a00f_read_channel(data, chan, val); 1291 iio_device_release_direct_mode(indio_dev); 1292 } 1293 return err < 0 ? err : IIO_VAL_INT; 1294 } 1295 1296 static const struct iio_event_spec gp2ap020a00f_event_spec_light[] = { 1297 { 1298 .type = IIO_EV_TYPE_THRESH, 1299 .dir = IIO_EV_DIR_RISING, 1300 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1301 BIT(IIO_EV_INFO_ENABLE), 1302 }, { 1303 .type = IIO_EV_TYPE_THRESH, 1304 .dir = IIO_EV_DIR_FALLING, 1305 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1306 BIT(IIO_EV_INFO_ENABLE), 1307 }, 1308 }; 1309 1310 static const struct iio_event_spec gp2ap020a00f_event_spec_prox[] = { 1311 { 1312 .type = IIO_EV_TYPE_ROC, 1313 .dir = IIO_EV_DIR_RISING, 1314 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1315 BIT(IIO_EV_INFO_ENABLE), 1316 }, { 1317 .type = IIO_EV_TYPE_ROC, 1318 .dir = IIO_EV_DIR_FALLING, 1319 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1320 BIT(IIO_EV_INFO_ENABLE), 1321 }, 1322 }; 1323 1324 static const struct iio_chan_spec gp2ap020a00f_channels[] = { 1325 { 1326 .type = IIO_LIGHT, 1327 .channel2 = IIO_MOD_LIGHT_CLEAR, 1328 .modified = 1, 1329 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1330 .scan_type = { 1331 .sign = 'u', 1332 .realbits = 24, 1333 .shift = 0, 1334 .storagebits = 32, 1335 .endianness = IIO_LE, 1336 }, 1337 .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, 1338 .address = GP2AP020A00F_D0_L_REG, 1339 .event_spec = gp2ap020a00f_event_spec_light, 1340 .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_light), 1341 }, 1342 { 1343 .type = IIO_LIGHT, 1344 .channel2 = IIO_MOD_LIGHT_IR, 1345 .modified = 1, 1346 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1347 .scan_type = { 1348 .sign = 'u', 1349 .realbits = 24, 1350 .shift = 0, 1351 .storagebits = 32, 1352 .endianness = IIO_LE, 1353 }, 1354 .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_IR, 1355 .address = GP2AP020A00F_D1_L_REG, 1356 }, 1357 { 1358 .type = IIO_PROXIMITY, 1359 .modified = 0, 1360 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1361 .scan_type = { 1362 .sign = 'u', 1363 .realbits = 16, 1364 .shift = 0, 1365 .storagebits = 16, 1366 .endianness = IIO_LE, 1367 }, 1368 .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY, 1369 .address = GP2AP020A00F_D2_L_REG, 1370 .event_spec = gp2ap020a00f_event_spec_prox, 1371 .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_prox), 1372 }, 1373 IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP), 1374 }; 1375 1376 static const struct iio_info gp2ap020a00f_info = { 1377 .read_raw = &gp2ap020a00f_read_raw, 1378 .read_event_value = &gp2ap020a00f_read_event_val, 1379 .read_event_config = &gp2ap020a00f_read_event_config, 1380 .write_event_value = &gp2ap020a00f_write_event_val, 1381 .write_event_config = &gp2ap020a00f_write_event_config, 1382 }; 1383 1384 static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev) 1385 { 1386 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1387 int i, err = 0; 1388 1389 mutex_lock(&data->lock); 1390 1391 /* 1392 * Enable triggers according to the scan_mask. Enabling either 1393 * LIGHT_CLEAR or LIGHT_IR scan mode results in enabling ALS 1394 * module in the device, which generates samples in both D0 (clear) 1395 * and D1 (ir) registers. As the two registers are bound to the 1396 * two separate IIO channels they are treated in the driver logic 1397 * as if they were controlled independently. 1398 */ 1399 iio_for_each_active_channel(indio_dev, i) { 1400 switch (i) { 1401 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1402 err = gp2ap020a00f_exec_cmd(data, 1403 GP2AP020A00F_CMD_TRIGGER_CLEAR_EN); 1404 break; 1405 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1406 err = gp2ap020a00f_exec_cmd(data, 1407 GP2AP020A00F_CMD_TRIGGER_IR_EN); 1408 break; 1409 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1410 err = gp2ap020a00f_exec_cmd(data, 1411 GP2AP020A00F_CMD_TRIGGER_PROX_EN); 1412 break; 1413 } 1414 } 1415 1416 if (err < 0) 1417 goto error_unlock; 1418 1419 data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); 1420 if (!data->buffer) 1421 err = -ENOMEM; 1422 1423 error_unlock: 1424 mutex_unlock(&data->lock); 1425 1426 return err; 1427 } 1428 1429 static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev) 1430 { 1431 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1432 int i, err = 0; 1433 1434 mutex_lock(&data->lock); 1435 1436 iio_for_each_active_channel(indio_dev, i) { 1437 switch (i) { 1438 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1439 err = gp2ap020a00f_exec_cmd(data, 1440 GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS); 1441 break; 1442 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1443 err = gp2ap020a00f_exec_cmd(data, 1444 GP2AP020A00F_CMD_TRIGGER_IR_DIS); 1445 break; 1446 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1447 err = gp2ap020a00f_exec_cmd(data, 1448 GP2AP020A00F_CMD_TRIGGER_PROX_DIS); 1449 break; 1450 } 1451 } 1452 1453 if (err == 0) 1454 kfree(data->buffer); 1455 1456 mutex_unlock(&data->lock); 1457 1458 return err; 1459 } 1460 1461 static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { 1462 .postenable = &gp2ap020a00f_buffer_postenable, 1463 .predisable = &gp2ap020a00f_buffer_predisable, 1464 }; 1465 1466 static int gp2ap020a00f_probe(struct i2c_client *client) 1467 { 1468 const struct i2c_device_id *id = i2c_client_get_device_id(client); 1469 struct gp2ap020a00f_data *data; 1470 struct iio_dev *indio_dev; 1471 struct regmap *regmap; 1472 int err; 1473 1474 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1475 if (!indio_dev) 1476 return -ENOMEM; 1477 1478 data = iio_priv(indio_dev); 1479 1480 data->vled_reg = devm_regulator_get(&client->dev, "vled"); 1481 if (IS_ERR(data->vled_reg)) 1482 return PTR_ERR(data->vled_reg); 1483 1484 err = regulator_enable(data->vled_reg); 1485 if (err) 1486 return err; 1487 1488 regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config); 1489 if (IS_ERR(regmap)) { 1490 dev_err(&client->dev, "Regmap initialization failed.\n"); 1491 err = PTR_ERR(regmap); 1492 goto error_regulator_disable; 1493 } 1494 1495 /* Initialize device registers */ 1496 err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG, 1497 gp2ap020a00f_reg_init_tab, 1498 ARRAY_SIZE(gp2ap020a00f_reg_init_tab)); 1499 1500 if (err < 0) { 1501 dev_err(&client->dev, "Device initialization failed.\n"); 1502 goto error_regulator_disable; 1503 } 1504 1505 i2c_set_clientdata(client, indio_dev); 1506 1507 data->client = client; 1508 data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN; 1509 data->regmap = regmap; 1510 init_waitqueue_head(&data->data_ready_queue); 1511 1512 mutex_init(&data->lock); 1513 indio_dev->channels = gp2ap020a00f_channels; 1514 indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels); 1515 indio_dev->info = &gp2ap020a00f_info; 1516 indio_dev->name = id->name; 1517 indio_dev->modes = INDIO_DIRECT_MODE; 1518 1519 /* Allocate buffer */ 1520 err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, 1521 &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops); 1522 if (err < 0) 1523 goto error_regulator_disable; 1524 1525 /* Allocate trigger */ 1526 data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger", 1527 indio_dev->name); 1528 if (data->trig == NULL) { 1529 err = -ENOMEM; 1530 dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n"); 1531 goto error_uninit_buffer; 1532 } 1533 1534 /* This needs to be requested here for read_raw calls to work. */ 1535 err = request_threaded_irq(client->irq, NULL, 1536 &gp2ap020a00f_thresh_event_handler, 1537 IRQF_TRIGGER_FALLING | 1538 IRQF_ONESHOT, 1539 "gp2ap020a00f_als_event", 1540 indio_dev); 1541 if (err < 0) { 1542 dev_err(&client->dev, "Irq request failed.\n"); 1543 goto error_uninit_buffer; 1544 } 1545 1546 init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work); 1547 1548 err = iio_trigger_register(data->trig); 1549 if (err < 0) { 1550 dev_err(&client->dev, "Failed to register iio trigger.\n"); 1551 goto error_free_irq; 1552 } 1553 1554 err = iio_device_register(indio_dev); 1555 if (err < 0) 1556 goto error_trigger_unregister; 1557 1558 return 0; 1559 1560 error_trigger_unregister: 1561 iio_trigger_unregister(data->trig); 1562 error_free_irq: 1563 free_irq(client->irq, indio_dev); 1564 error_uninit_buffer: 1565 iio_triggered_buffer_cleanup(indio_dev); 1566 error_regulator_disable: 1567 regulator_disable(data->vled_reg); 1568 1569 return err; 1570 } 1571 1572 static void gp2ap020a00f_remove(struct i2c_client *client) 1573 { 1574 struct iio_dev *indio_dev = i2c_get_clientdata(client); 1575 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1576 int err; 1577 1578 err = gp2ap020a00f_set_operation_mode(data, 1579 GP2AP020A00F_OPMODE_SHUTDOWN); 1580 if (err < 0) 1581 dev_err(&indio_dev->dev, "Failed to power off the device.\n"); 1582 1583 iio_device_unregister(indio_dev); 1584 iio_trigger_unregister(data->trig); 1585 free_irq(client->irq, indio_dev); 1586 iio_triggered_buffer_cleanup(indio_dev); 1587 regulator_disable(data->vled_reg); 1588 } 1589 1590 static const struct i2c_device_id gp2ap020a00f_id[] = { 1591 { GP2A_I2C_NAME }, 1592 { } 1593 }; 1594 1595 MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); 1596 1597 static const struct of_device_id gp2ap020a00f_of_match[] = { 1598 { .compatible = "sharp,gp2ap020a00f" }, 1599 { } 1600 }; 1601 MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); 1602 1603 static struct i2c_driver gp2ap020a00f_driver = { 1604 .driver = { 1605 .name = GP2A_I2C_NAME, 1606 .of_match_table = gp2ap020a00f_of_match, 1607 }, 1608 .probe = gp2ap020a00f_probe, 1609 .remove = gp2ap020a00f_remove, 1610 .id_table = gp2ap020a00f_id, 1611 }; 1612 1613 module_i2c_driver(gp2ap020a00f_driver); 1614 1615 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); 1616 MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver"); 1617 MODULE_LICENSE("GPL v2"); 1618