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 <asm/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 for_each_set_bit(i, indio_dev->active_scan_mask, 969 indio_dev->masklength) { 970 ret = regmap_bulk_read(priv->regmap, 971 GP2AP020A00F_DATA_REG(i), 972 &priv->buffer[d_size], 2); 973 if (ret < 0) 974 goto done; 975 976 if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR || 977 i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) { 978 out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]); 979 gp2ap020a00f_output_to_lux(priv, &out_val); 980 981 put_unaligned_le32(out_val, &priv->buffer[d_size]); 982 d_size += 4; 983 } else { 984 d_size += 2; 985 } 986 } 987 988 iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer, 989 pf->timestamp); 990 done: 991 iio_trigger_notify_done(indio_dev->trig); 992 993 return IRQ_HANDLED; 994 } 995 996 static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan, 997 enum iio_event_direction event_dir) 998 { 999 switch (chan->type) { 1000 case IIO_PROXIMITY: 1001 if (event_dir == IIO_EV_DIR_RISING) 1002 return GP2AP020A00F_PH_L_REG; 1003 else 1004 return GP2AP020A00F_PL_L_REG; 1005 case IIO_LIGHT: 1006 if (event_dir == IIO_EV_DIR_RISING) 1007 return GP2AP020A00F_TH_L_REG; 1008 else 1009 return GP2AP020A00F_TL_L_REG; 1010 default: 1011 break; 1012 } 1013 1014 return -EINVAL; 1015 } 1016 1017 static int gp2ap020a00f_write_event_val(struct iio_dev *indio_dev, 1018 const struct iio_chan_spec *chan, 1019 enum iio_event_type type, 1020 enum iio_event_direction dir, 1021 enum iio_event_info info, 1022 int val, int val2) 1023 { 1024 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1025 bool event_en = false; 1026 u8 thresh_val_id; 1027 u8 thresh_reg_l; 1028 int err = 0; 1029 1030 mutex_lock(&data->lock); 1031 1032 thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); 1033 thresh_val_id = GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l); 1034 1035 if (thresh_val_id > GP2AP020A00F_THRESH_PH) { 1036 err = -EINVAL; 1037 goto error_unlock; 1038 } 1039 1040 switch (thresh_reg_l) { 1041 case GP2AP020A00F_TH_L_REG: 1042 event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, 1043 &data->flags); 1044 break; 1045 case GP2AP020A00F_TL_L_REG: 1046 event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, 1047 &data->flags); 1048 break; 1049 case GP2AP020A00F_PH_L_REG: 1050 if (val == 0) { 1051 err = -EINVAL; 1052 goto error_unlock; 1053 } 1054 event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, 1055 &data->flags); 1056 break; 1057 case GP2AP020A00F_PL_L_REG: 1058 if (val == 0) { 1059 err = -EINVAL; 1060 goto error_unlock; 1061 } 1062 event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, 1063 &data->flags); 1064 break; 1065 } 1066 1067 data->thresh_val[thresh_val_id] = val; 1068 err = gp2ap020a00f_write_event_threshold(data, thresh_val_id, 1069 event_en); 1070 error_unlock: 1071 mutex_unlock(&data->lock); 1072 1073 return err; 1074 } 1075 1076 static int gp2ap020a00f_read_event_val(struct iio_dev *indio_dev, 1077 const struct iio_chan_spec *chan, 1078 enum iio_event_type type, 1079 enum iio_event_direction dir, 1080 enum iio_event_info info, 1081 int *val, int *val2) 1082 { 1083 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1084 u8 thresh_reg_l; 1085 int err = IIO_VAL_INT; 1086 1087 mutex_lock(&data->lock); 1088 1089 thresh_reg_l = gp2ap020a00f_get_thresh_reg(chan, dir); 1090 1091 if (thresh_reg_l > GP2AP020A00F_PH_L_REG) { 1092 err = -EINVAL; 1093 goto error_unlock; 1094 } 1095 1096 *val = data->thresh_val[GP2AP020A00F_THRESH_VAL_ID(thresh_reg_l)]; 1097 1098 error_unlock: 1099 mutex_unlock(&data->lock); 1100 1101 return err; 1102 } 1103 1104 static int gp2ap020a00f_write_prox_event_config(struct iio_dev *indio_dev, 1105 int state) 1106 { 1107 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1108 enum gp2ap020a00f_cmd cmd_high_ev, cmd_low_ev; 1109 int err; 1110 1111 cmd_high_ev = state ? GP2AP020A00F_CMD_PROX_HIGH_EV_EN : 1112 GP2AP020A00F_CMD_PROX_HIGH_EV_DIS; 1113 cmd_low_ev = state ? GP2AP020A00F_CMD_PROX_LOW_EV_EN : 1114 GP2AP020A00F_CMD_PROX_LOW_EV_DIS; 1115 1116 /* 1117 * In order to enable proximity detection feature in the device 1118 * both high and low threshold registers have to be written 1119 * with different values, greater than zero. 1120 */ 1121 if (state) { 1122 if (data->thresh_val[GP2AP020A00F_THRESH_PL] == 0) 1123 return -EINVAL; 1124 1125 if (data->thresh_val[GP2AP020A00F_THRESH_PH] == 0) 1126 return -EINVAL; 1127 } 1128 1129 err = gp2ap020a00f_exec_cmd(data, cmd_high_ev); 1130 if (err < 0) 1131 return err; 1132 1133 err = gp2ap020a00f_exec_cmd(data, cmd_low_ev); 1134 if (err < 0) 1135 return err; 1136 1137 free_irq(data->client->irq, indio_dev); 1138 1139 if (state) 1140 err = request_threaded_irq(data->client->irq, NULL, 1141 &gp2ap020a00f_prox_sensing_handler, 1142 IRQF_TRIGGER_RISING | 1143 IRQF_TRIGGER_FALLING | 1144 IRQF_ONESHOT, 1145 "gp2ap020a00f_prox_sensing", 1146 indio_dev); 1147 else { 1148 err = request_threaded_irq(data->client->irq, NULL, 1149 &gp2ap020a00f_thresh_event_handler, 1150 IRQF_TRIGGER_FALLING | 1151 IRQF_ONESHOT, 1152 "gp2ap020a00f_thresh_event", 1153 indio_dev); 1154 } 1155 1156 return err; 1157 } 1158 1159 static int gp2ap020a00f_write_event_config(struct iio_dev *indio_dev, 1160 const struct iio_chan_spec *chan, 1161 enum iio_event_type type, 1162 enum iio_event_direction dir, 1163 int state) 1164 { 1165 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1166 enum gp2ap020a00f_cmd cmd; 1167 int err; 1168 1169 mutex_lock(&data->lock); 1170 1171 switch (chan->type) { 1172 case IIO_PROXIMITY: 1173 err = gp2ap020a00f_write_prox_event_config(indio_dev, state); 1174 break; 1175 case IIO_LIGHT: 1176 if (dir == IIO_EV_DIR_RISING) { 1177 cmd = state ? GP2AP020A00F_CMD_ALS_HIGH_EV_EN : 1178 GP2AP020A00F_CMD_ALS_HIGH_EV_DIS; 1179 err = gp2ap020a00f_exec_cmd(data, cmd); 1180 } else { 1181 cmd = state ? GP2AP020A00F_CMD_ALS_LOW_EV_EN : 1182 GP2AP020A00F_CMD_ALS_LOW_EV_DIS; 1183 err = gp2ap020a00f_exec_cmd(data, cmd); 1184 } 1185 break; 1186 default: 1187 err = -EINVAL; 1188 } 1189 1190 mutex_unlock(&data->lock); 1191 1192 return err; 1193 } 1194 1195 static int gp2ap020a00f_read_event_config(struct iio_dev *indio_dev, 1196 const struct iio_chan_spec *chan, 1197 enum iio_event_type type, 1198 enum iio_event_direction dir) 1199 { 1200 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1201 int event_en = 0; 1202 1203 mutex_lock(&data->lock); 1204 1205 switch (chan->type) { 1206 case IIO_PROXIMITY: 1207 if (dir == IIO_EV_DIR_RISING) 1208 event_en = test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, 1209 &data->flags); 1210 else 1211 event_en = test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, 1212 &data->flags); 1213 break; 1214 case IIO_LIGHT: 1215 if (dir == IIO_EV_DIR_RISING) 1216 event_en = test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, 1217 &data->flags); 1218 else 1219 event_en = test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, 1220 &data->flags); 1221 break; 1222 default: 1223 event_en = -EINVAL; 1224 break; 1225 } 1226 1227 mutex_unlock(&data->lock); 1228 1229 return event_en; 1230 } 1231 1232 static int gp2ap020a00f_read_channel(struct gp2ap020a00f_data *data, 1233 struct iio_chan_spec const *chan, int *val) 1234 { 1235 enum gp2ap020a00f_cmd cmd; 1236 int err; 1237 1238 switch (chan->scan_index) { 1239 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1240 cmd = GP2AP020A00F_CMD_READ_RAW_CLEAR; 1241 break; 1242 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1243 cmd = GP2AP020A00F_CMD_READ_RAW_IR; 1244 break; 1245 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1246 cmd = GP2AP020A00F_CMD_READ_RAW_PROXIMITY; 1247 break; 1248 default: 1249 return -EINVAL; 1250 } 1251 1252 err = gp2ap020a00f_exec_cmd(data, cmd); 1253 if (err < 0) { 1254 dev_err(&data->client->dev, 1255 "gp2ap020a00f_exec_cmd failed\n"); 1256 goto error_ret; 1257 } 1258 1259 err = gp2ap020a00f_read_output(data, chan->address, val); 1260 if (err < 0) 1261 dev_err(&data->client->dev, 1262 "gp2ap020a00f_read_output failed\n"); 1263 1264 err = gp2ap020a00f_set_operation_mode(data, 1265 GP2AP020A00F_OPMODE_SHUTDOWN); 1266 if (err < 0) 1267 dev_err(&data->client->dev, 1268 "Failed to shut down the device.\n"); 1269 1270 if (cmd == GP2AP020A00F_CMD_READ_RAW_CLEAR || 1271 cmd == GP2AP020A00F_CMD_READ_RAW_IR) 1272 gp2ap020a00f_output_to_lux(data, val); 1273 1274 error_ret: 1275 return err; 1276 } 1277 1278 static int gp2ap020a00f_read_raw(struct iio_dev *indio_dev, 1279 struct iio_chan_spec const *chan, 1280 int *val, int *val2, 1281 long mask) 1282 { 1283 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1284 int err = -EINVAL; 1285 1286 if (mask == IIO_CHAN_INFO_RAW) { 1287 err = iio_device_claim_direct_mode(indio_dev); 1288 if (err) 1289 return err; 1290 1291 err = gp2ap020a00f_read_channel(data, chan, val); 1292 iio_device_release_direct_mode(indio_dev); 1293 } 1294 return err < 0 ? err : IIO_VAL_INT; 1295 } 1296 1297 static const struct iio_event_spec gp2ap020a00f_event_spec_light[] = { 1298 { 1299 .type = IIO_EV_TYPE_THRESH, 1300 .dir = IIO_EV_DIR_RISING, 1301 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1302 BIT(IIO_EV_INFO_ENABLE), 1303 }, { 1304 .type = IIO_EV_TYPE_THRESH, 1305 .dir = IIO_EV_DIR_FALLING, 1306 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1307 BIT(IIO_EV_INFO_ENABLE), 1308 }, 1309 }; 1310 1311 static const struct iio_event_spec gp2ap020a00f_event_spec_prox[] = { 1312 { 1313 .type = IIO_EV_TYPE_ROC, 1314 .dir = IIO_EV_DIR_RISING, 1315 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1316 BIT(IIO_EV_INFO_ENABLE), 1317 }, { 1318 .type = IIO_EV_TYPE_ROC, 1319 .dir = IIO_EV_DIR_FALLING, 1320 .mask_separate = BIT(IIO_EV_INFO_VALUE) | 1321 BIT(IIO_EV_INFO_ENABLE), 1322 }, 1323 }; 1324 1325 static const struct iio_chan_spec gp2ap020a00f_channels[] = { 1326 { 1327 .type = IIO_LIGHT, 1328 .channel2 = IIO_MOD_LIGHT_CLEAR, 1329 .modified = 1, 1330 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1331 .scan_type = { 1332 .sign = 'u', 1333 .realbits = 24, 1334 .shift = 0, 1335 .storagebits = 32, 1336 .endianness = IIO_LE, 1337 }, 1338 .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR, 1339 .address = GP2AP020A00F_D0_L_REG, 1340 .event_spec = gp2ap020a00f_event_spec_light, 1341 .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_light), 1342 }, 1343 { 1344 .type = IIO_LIGHT, 1345 .channel2 = IIO_MOD_LIGHT_IR, 1346 .modified = 1, 1347 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1348 .scan_type = { 1349 .sign = 'u', 1350 .realbits = 24, 1351 .shift = 0, 1352 .storagebits = 32, 1353 .endianness = IIO_LE, 1354 }, 1355 .scan_index = GP2AP020A00F_SCAN_MODE_LIGHT_IR, 1356 .address = GP2AP020A00F_D1_L_REG, 1357 }, 1358 { 1359 .type = IIO_PROXIMITY, 1360 .modified = 0, 1361 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 1362 .scan_type = { 1363 .sign = 'u', 1364 .realbits = 16, 1365 .shift = 0, 1366 .storagebits = 16, 1367 .endianness = IIO_LE, 1368 }, 1369 .scan_index = GP2AP020A00F_SCAN_MODE_PROXIMITY, 1370 .address = GP2AP020A00F_D2_L_REG, 1371 .event_spec = gp2ap020a00f_event_spec_prox, 1372 .num_event_specs = ARRAY_SIZE(gp2ap020a00f_event_spec_prox), 1373 }, 1374 IIO_CHAN_SOFT_TIMESTAMP(GP2AP020A00F_CHAN_TIMESTAMP), 1375 }; 1376 1377 static const struct iio_info gp2ap020a00f_info = { 1378 .read_raw = &gp2ap020a00f_read_raw, 1379 .read_event_value = &gp2ap020a00f_read_event_val, 1380 .read_event_config = &gp2ap020a00f_read_event_config, 1381 .write_event_value = &gp2ap020a00f_write_event_val, 1382 .write_event_config = &gp2ap020a00f_write_event_config, 1383 }; 1384 1385 static int gp2ap020a00f_buffer_postenable(struct iio_dev *indio_dev) 1386 { 1387 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1388 int i, err = 0; 1389 1390 mutex_lock(&data->lock); 1391 1392 /* 1393 * Enable triggers according to the scan_mask. Enabling either 1394 * LIGHT_CLEAR or LIGHT_IR scan mode results in enabling ALS 1395 * module in the device, which generates samples in both D0 (clear) 1396 * and D1 (ir) registers. As the two registers are bound to the 1397 * two separate IIO channels they are treated in the driver logic 1398 * as if they were controlled independently. 1399 */ 1400 for_each_set_bit(i, indio_dev->active_scan_mask, 1401 indio_dev->masklength) { 1402 switch (i) { 1403 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1404 err = gp2ap020a00f_exec_cmd(data, 1405 GP2AP020A00F_CMD_TRIGGER_CLEAR_EN); 1406 break; 1407 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1408 err = gp2ap020a00f_exec_cmd(data, 1409 GP2AP020A00F_CMD_TRIGGER_IR_EN); 1410 break; 1411 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1412 err = gp2ap020a00f_exec_cmd(data, 1413 GP2AP020A00F_CMD_TRIGGER_PROX_EN); 1414 break; 1415 } 1416 } 1417 1418 if (err < 0) 1419 goto error_unlock; 1420 1421 data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); 1422 if (!data->buffer) 1423 err = -ENOMEM; 1424 1425 error_unlock: 1426 mutex_unlock(&data->lock); 1427 1428 return err; 1429 } 1430 1431 static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev) 1432 { 1433 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1434 int i, err = 0; 1435 1436 mutex_lock(&data->lock); 1437 1438 for_each_set_bit(i, indio_dev->active_scan_mask, 1439 indio_dev->masklength) { 1440 switch (i) { 1441 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR: 1442 err = gp2ap020a00f_exec_cmd(data, 1443 GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS); 1444 break; 1445 case GP2AP020A00F_SCAN_MODE_LIGHT_IR: 1446 err = gp2ap020a00f_exec_cmd(data, 1447 GP2AP020A00F_CMD_TRIGGER_IR_DIS); 1448 break; 1449 case GP2AP020A00F_SCAN_MODE_PROXIMITY: 1450 err = gp2ap020a00f_exec_cmd(data, 1451 GP2AP020A00F_CMD_TRIGGER_PROX_DIS); 1452 break; 1453 } 1454 } 1455 1456 if (err == 0) 1457 kfree(data->buffer); 1458 1459 mutex_unlock(&data->lock); 1460 1461 return err; 1462 } 1463 1464 static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { 1465 .postenable = &gp2ap020a00f_buffer_postenable, 1466 .predisable = &gp2ap020a00f_buffer_predisable, 1467 }; 1468 1469 static int gp2ap020a00f_probe(struct i2c_client *client) 1470 { 1471 const struct i2c_device_id *id = i2c_client_get_device_id(client); 1472 struct gp2ap020a00f_data *data; 1473 struct iio_dev *indio_dev; 1474 struct regmap *regmap; 1475 int err; 1476 1477 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1478 if (!indio_dev) 1479 return -ENOMEM; 1480 1481 data = iio_priv(indio_dev); 1482 1483 data->vled_reg = devm_regulator_get(&client->dev, "vled"); 1484 if (IS_ERR(data->vled_reg)) 1485 return PTR_ERR(data->vled_reg); 1486 1487 err = regulator_enable(data->vled_reg); 1488 if (err) 1489 return err; 1490 1491 regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config); 1492 if (IS_ERR(regmap)) { 1493 dev_err(&client->dev, "Regmap initialization failed.\n"); 1494 err = PTR_ERR(regmap); 1495 goto error_regulator_disable; 1496 } 1497 1498 /* Initialize device registers */ 1499 err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG, 1500 gp2ap020a00f_reg_init_tab, 1501 ARRAY_SIZE(gp2ap020a00f_reg_init_tab)); 1502 1503 if (err < 0) { 1504 dev_err(&client->dev, "Device initialization failed.\n"); 1505 goto error_regulator_disable; 1506 } 1507 1508 i2c_set_clientdata(client, indio_dev); 1509 1510 data->client = client; 1511 data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN; 1512 data->regmap = regmap; 1513 init_waitqueue_head(&data->data_ready_queue); 1514 1515 mutex_init(&data->lock); 1516 indio_dev->channels = gp2ap020a00f_channels; 1517 indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels); 1518 indio_dev->info = &gp2ap020a00f_info; 1519 indio_dev->name = id->name; 1520 indio_dev->modes = INDIO_DIRECT_MODE; 1521 1522 /* Allocate buffer */ 1523 err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, 1524 &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops); 1525 if (err < 0) 1526 goto error_regulator_disable; 1527 1528 /* Allocate trigger */ 1529 data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger", 1530 indio_dev->name); 1531 if (data->trig == NULL) { 1532 err = -ENOMEM; 1533 dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n"); 1534 goto error_uninit_buffer; 1535 } 1536 1537 /* This needs to be requested here for read_raw calls to work. */ 1538 err = request_threaded_irq(client->irq, NULL, 1539 &gp2ap020a00f_thresh_event_handler, 1540 IRQF_TRIGGER_FALLING | 1541 IRQF_ONESHOT, 1542 "gp2ap020a00f_als_event", 1543 indio_dev); 1544 if (err < 0) { 1545 dev_err(&client->dev, "Irq request failed.\n"); 1546 goto error_uninit_buffer; 1547 } 1548 1549 init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work); 1550 1551 err = iio_trigger_register(data->trig); 1552 if (err < 0) { 1553 dev_err(&client->dev, "Failed to register iio trigger.\n"); 1554 goto error_free_irq; 1555 } 1556 1557 err = iio_device_register(indio_dev); 1558 if (err < 0) 1559 goto error_trigger_unregister; 1560 1561 return 0; 1562 1563 error_trigger_unregister: 1564 iio_trigger_unregister(data->trig); 1565 error_free_irq: 1566 free_irq(client->irq, indio_dev); 1567 error_uninit_buffer: 1568 iio_triggered_buffer_cleanup(indio_dev); 1569 error_regulator_disable: 1570 regulator_disable(data->vled_reg); 1571 1572 return err; 1573 } 1574 1575 static void gp2ap020a00f_remove(struct i2c_client *client) 1576 { 1577 struct iio_dev *indio_dev = i2c_get_clientdata(client); 1578 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1579 int err; 1580 1581 err = gp2ap020a00f_set_operation_mode(data, 1582 GP2AP020A00F_OPMODE_SHUTDOWN); 1583 if (err < 0) 1584 dev_err(&indio_dev->dev, "Failed to power off the device.\n"); 1585 1586 iio_device_unregister(indio_dev); 1587 iio_trigger_unregister(data->trig); 1588 free_irq(client->irq, indio_dev); 1589 iio_triggered_buffer_cleanup(indio_dev); 1590 regulator_disable(data->vled_reg); 1591 } 1592 1593 static const struct i2c_device_id gp2ap020a00f_id[] = { 1594 { GP2A_I2C_NAME }, 1595 { } 1596 }; 1597 1598 MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); 1599 1600 static const struct of_device_id gp2ap020a00f_of_match[] = { 1601 { .compatible = "sharp,gp2ap020a00f" }, 1602 { } 1603 }; 1604 MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); 1605 1606 static struct i2c_driver gp2ap020a00f_driver = { 1607 .driver = { 1608 .name = GP2A_I2C_NAME, 1609 .of_match_table = gp2ap020a00f_of_match, 1610 }, 1611 .probe = gp2ap020a00f_probe, 1612 .remove = gp2ap020a00f_remove, 1613 .id_table = gp2ap020a00f_id, 1614 }; 1615 1616 module_i2c_driver(gp2ap020a00f_driver); 1617 1618 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); 1619 MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver"); 1620 MODULE_LICENSE("GPL v2"); 1621