gp2ap020a00f.c (46203B)
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 188enum 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 200enum 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 220enum 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 232enum gp2ap020a00f_thresh_val_id { 233 GP2AP020A00F_THRESH_TL, 234 GP2AP020A00F_THRESH_TH, 235 GP2AP020A00F_THRESH_PL, 236 GP2AP020A00F_THRESH_PH, 237}; 238 239struct 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 255static 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 275static 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 291static 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 301static 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 367static 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 425static 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 433static 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 439static 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 468static 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 494static 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 685static 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 698static 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 717static 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 816static 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 823static 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 831static 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 866static 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 957done: 958 return IRQ_HANDLED; 959} 960 961static 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); 991done: 992 iio_trigger_notify_done(indio_dev->trig); 993 994 return IRQ_HANDLED; 995} 996 997static 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 1018static 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); 1071error_unlock: 1072 mutex_unlock(&data->lock); 1073 1074 return err; 1075} 1076 1077static 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 1099error_unlock: 1100 mutex_unlock(&data->lock); 1101 1102 return err; 1103} 1104 1105static 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 1160static 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 1196static 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 1233static 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 1275error_ret: 1276 return err; 1277} 1278 1279static 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 1298static 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 1312static 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 1326static 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 1378static 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 1386static 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 1426error_unlock: 1427 mutex_unlock(&data->lock); 1428 1429 return err; 1430} 1431 1432static 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 1465static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = { 1466 .postenable = &gp2ap020a00f_buffer_postenable, 1467 .predisable = &gp2ap020a00f_buffer_predisable, 1468}; 1469 1470static int gp2ap020a00f_probe(struct i2c_client *client, 1471 const struct i2c_device_id *id) 1472{ 1473 struct gp2ap020a00f_data *data; 1474 struct iio_dev *indio_dev; 1475 struct regmap *regmap; 1476 int err; 1477 1478 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 1479 if (!indio_dev) 1480 return -ENOMEM; 1481 1482 data = iio_priv(indio_dev); 1483 1484 data->vled_reg = devm_regulator_get(&client->dev, "vled"); 1485 if (IS_ERR(data->vled_reg)) 1486 return PTR_ERR(data->vled_reg); 1487 1488 err = regulator_enable(data->vled_reg); 1489 if (err) 1490 return err; 1491 1492 regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config); 1493 if (IS_ERR(regmap)) { 1494 dev_err(&client->dev, "Regmap initialization failed.\n"); 1495 err = PTR_ERR(regmap); 1496 goto error_regulator_disable; 1497 } 1498 1499 /* Initialize device registers */ 1500 err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG, 1501 gp2ap020a00f_reg_init_tab, 1502 ARRAY_SIZE(gp2ap020a00f_reg_init_tab)); 1503 1504 if (err < 0) { 1505 dev_err(&client->dev, "Device initialization failed.\n"); 1506 goto error_regulator_disable; 1507 } 1508 1509 i2c_set_clientdata(client, indio_dev); 1510 1511 data->client = client; 1512 data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN; 1513 data->regmap = regmap; 1514 init_waitqueue_head(&data->data_ready_queue); 1515 1516 mutex_init(&data->lock); 1517 indio_dev->channels = gp2ap020a00f_channels; 1518 indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels); 1519 indio_dev->info = &gp2ap020a00f_info; 1520 indio_dev->name = id->name; 1521 indio_dev->modes = INDIO_DIRECT_MODE; 1522 1523 /* Allocate buffer */ 1524 err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, 1525 &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops); 1526 if (err < 0) 1527 goto error_regulator_disable; 1528 1529 /* Allocate trigger */ 1530 data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger", 1531 indio_dev->name); 1532 if (data->trig == NULL) { 1533 err = -ENOMEM; 1534 dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n"); 1535 goto error_uninit_buffer; 1536 } 1537 1538 /* This needs to be requested here for read_raw calls to work. */ 1539 err = request_threaded_irq(client->irq, NULL, 1540 &gp2ap020a00f_thresh_event_handler, 1541 IRQF_TRIGGER_FALLING | 1542 IRQF_ONESHOT, 1543 "gp2ap020a00f_als_event", 1544 indio_dev); 1545 if (err < 0) { 1546 dev_err(&client->dev, "Irq request failed.\n"); 1547 goto error_uninit_buffer; 1548 } 1549 1550 init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work); 1551 1552 err = iio_trigger_register(data->trig); 1553 if (err < 0) { 1554 dev_err(&client->dev, "Failed to register iio trigger.\n"); 1555 goto error_free_irq; 1556 } 1557 1558 err = iio_device_register(indio_dev); 1559 if (err < 0) 1560 goto error_trigger_unregister; 1561 1562 return 0; 1563 1564error_trigger_unregister: 1565 iio_trigger_unregister(data->trig); 1566error_free_irq: 1567 free_irq(client->irq, indio_dev); 1568error_uninit_buffer: 1569 iio_triggered_buffer_cleanup(indio_dev); 1570error_regulator_disable: 1571 regulator_disable(data->vled_reg); 1572 1573 return err; 1574} 1575 1576static int gp2ap020a00f_remove(struct i2c_client *client) 1577{ 1578 struct iio_dev *indio_dev = i2c_get_clientdata(client); 1579 struct gp2ap020a00f_data *data = iio_priv(indio_dev); 1580 int err; 1581 1582 err = gp2ap020a00f_set_operation_mode(data, 1583 GP2AP020A00F_OPMODE_SHUTDOWN); 1584 if (err < 0) 1585 dev_err(&indio_dev->dev, "Failed to power off the device.\n"); 1586 1587 iio_device_unregister(indio_dev); 1588 iio_trigger_unregister(data->trig); 1589 free_irq(client->irq, indio_dev); 1590 iio_triggered_buffer_cleanup(indio_dev); 1591 regulator_disable(data->vled_reg); 1592 1593 return 0; 1594} 1595 1596static const struct i2c_device_id gp2ap020a00f_id[] = { 1597 { GP2A_I2C_NAME, 0 }, 1598 { } 1599}; 1600 1601MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id); 1602 1603static const struct of_device_id gp2ap020a00f_of_match[] = { 1604 { .compatible = "sharp,gp2ap020a00f" }, 1605 { } 1606}; 1607MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match); 1608 1609static struct i2c_driver gp2ap020a00f_driver = { 1610 .driver = { 1611 .name = GP2A_I2C_NAME, 1612 .of_match_table = gp2ap020a00f_of_match, 1613 }, 1614 .probe = gp2ap020a00f_probe, 1615 .remove = gp2ap020a00f_remove, 1616 .id_table = gp2ap020a00f_id, 1617}; 1618 1619module_i2c_driver(gp2ap020a00f_driver); 1620 1621MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>"); 1622MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver"); 1623MODULE_LICENSE("GPL v2");