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