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