root/drivers/iio/light/gp2ap020a00f.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gp2ap020a00f_is_volatile_reg
  2. gp2ap020a00f_set_operation_mode
  3. gp2ap020a00f_als_enabled
  4. gp2ap020a00f_prox_detect_enabled
  5. gp2ap020a00f_write_event_threshold
  6. gp2ap020a00f_alter_opmode
  7. gp2ap020a00f_exec_cmd
  8. wait_conversion_complete_irq
  9. gp2ap020a00f_read_output
  10. gp2ap020a00f_adjust_lux_mode
  11. gp2ap020a00f_output_to_lux
  12. gp2ap020a00f_iio_trigger_work
  13. gp2ap020a00f_prox_sensing_handler
  14. gp2ap020a00f_thresh_event_handler
  15. gp2ap020a00f_trigger_handler
  16. gp2ap020a00f_get_thresh_reg
  17. gp2ap020a00f_write_event_val
  18. gp2ap020a00f_read_event_val
  19. gp2ap020a00f_write_prox_event_config
  20. gp2ap020a00f_write_event_config
  21. gp2ap020a00f_read_event_config
  22. gp2ap020a00f_read_channel
  23. gp2ap020a00f_read_raw
  24. gp2ap020a00f_buffer_postenable
  25. gp2ap020a00f_buffer_predisable
  26. gp2ap020a00f_probe
  27. gp2ap020a00f_remove

   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/mutex.h>
  42 #include <linux/of.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                 goto error_unlock;
1426         }
1427 
1428         err = iio_triggered_buffer_postenable(indio_dev);
1429 
1430 error_unlock:
1431         mutex_unlock(&data->lock);
1432 
1433         return err;
1434 }
1435 
1436 static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
1437 {
1438         struct gp2ap020a00f_data *data = iio_priv(indio_dev);
1439         int i, err;
1440 
1441         mutex_lock(&data->lock);
1442 
1443         err = iio_triggered_buffer_predisable(indio_dev);
1444         if (err < 0)
1445                 goto error_unlock;
1446 
1447         for_each_set_bit(i, indio_dev->active_scan_mask,
1448                 indio_dev->masklength) {
1449                 switch (i) {
1450                 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
1451                         err = gp2ap020a00f_exec_cmd(data,
1452                                         GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS);
1453                         break;
1454                 case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
1455                         err = gp2ap020a00f_exec_cmd(data,
1456                                         GP2AP020A00F_CMD_TRIGGER_IR_DIS);
1457                         break;
1458                 case GP2AP020A00F_SCAN_MODE_PROXIMITY:
1459                         err = gp2ap020a00f_exec_cmd(data,
1460                                         GP2AP020A00F_CMD_TRIGGER_PROX_DIS);
1461                         break;
1462                 }
1463         }
1464 
1465         if (err == 0)
1466                 kfree(data->buffer);
1467 
1468 error_unlock:
1469         mutex_unlock(&data->lock);
1470 
1471         return err;
1472 }
1473 
1474 static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
1475         .postenable = &gp2ap020a00f_buffer_postenable,
1476         .predisable = &gp2ap020a00f_buffer_predisable,
1477 };
1478 
1479 static const struct iio_trigger_ops gp2ap020a00f_trigger_ops = {
1480 };
1481 
1482 static int gp2ap020a00f_probe(struct i2c_client *client,
1483                                 const struct i2c_device_id *id)
1484 {
1485         struct gp2ap020a00f_data *data;
1486         struct iio_dev *indio_dev;
1487         struct regmap *regmap;
1488         int err;
1489 
1490         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
1491         if (!indio_dev)
1492                 return -ENOMEM;
1493 
1494         data = iio_priv(indio_dev);
1495 
1496         data->vled_reg = devm_regulator_get(&client->dev, "vled");
1497         if (IS_ERR(data->vled_reg))
1498                 return PTR_ERR(data->vled_reg);
1499 
1500         err = regulator_enable(data->vled_reg);
1501         if (err)
1502                 return err;
1503 
1504         regmap = devm_regmap_init_i2c(client, &gp2ap020a00f_regmap_config);
1505         if (IS_ERR(regmap)) {
1506                 dev_err(&client->dev, "Regmap initialization failed.\n");
1507                 err = PTR_ERR(regmap);
1508                 goto error_regulator_disable;
1509         }
1510 
1511         /* Initialize device registers */
1512         err = regmap_bulk_write(regmap, GP2AP020A00F_OP_REG,
1513                         gp2ap020a00f_reg_init_tab,
1514                         ARRAY_SIZE(gp2ap020a00f_reg_init_tab));
1515 
1516         if (err < 0) {
1517                 dev_err(&client->dev, "Device initialization failed.\n");
1518                 goto error_regulator_disable;
1519         }
1520 
1521         i2c_set_clientdata(client, indio_dev);
1522 
1523         data->client = client;
1524         data->cur_opmode = GP2AP020A00F_OPMODE_SHUTDOWN;
1525         data->regmap = regmap;
1526         init_waitqueue_head(&data->data_ready_queue);
1527 
1528         mutex_init(&data->lock);
1529         indio_dev->dev.parent = &client->dev;
1530         indio_dev->channels = gp2ap020a00f_channels;
1531         indio_dev->num_channels = ARRAY_SIZE(gp2ap020a00f_channels);
1532         indio_dev->info = &gp2ap020a00f_info;
1533         indio_dev->name = id->name;
1534         indio_dev->modes = INDIO_DIRECT_MODE;
1535 
1536         /* Allocate buffer */
1537         err = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,
1538                 &gp2ap020a00f_trigger_handler, &gp2ap020a00f_buffer_setup_ops);
1539         if (err < 0)
1540                 goto error_regulator_disable;
1541 
1542         /* Allocate trigger */
1543         data->trig = devm_iio_trigger_alloc(&client->dev, "%s-trigger",
1544                                                         indio_dev->name);
1545         if (data->trig == NULL) {
1546                 err = -ENOMEM;
1547                 dev_err(&indio_dev->dev, "Failed to allocate iio trigger.\n");
1548                 goto error_uninit_buffer;
1549         }
1550 
1551         /* This needs to be requested here for read_raw calls to work. */
1552         err = request_threaded_irq(client->irq, NULL,
1553                                    &gp2ap020a00f_thresh_event_handler,
1554                                    IRQF_TRIGGER_FALLING |
1555                                    IRQF_ONESHOT,
1556                                    "gp2ap020a00f_als_event",
1557                                    indio_dev);
1558         if (err < 0) {
1559                 dev_err(&client->dev, "Irq request failed.\n");
1560                 goto error_uninit_buffer;
1561         }
1562 
1563         data->trig->ops = &gp2ap020a00f_trigger_ops;
1564         data->trig->dev.parent = &data->client->dev;
1565 
1566         init_irq_work(&data->work, gp2ap020a00f_iio_trigger_work);
1567 
1568         err = iio_trigger_register(data->trig);
1569         if (err < 0) {
1570                 dev_err(&client->dev, "Failed to register iio trigger.\n");
1571                 goto error_free_irq;
1572         }
1573 
1574         err = iio_device_register(indio_dev);
1575         if (err < 0)
1576                 goto error_trigger_unregister;
1577 
1578         return 0;
1579 
1580 error_trigger_unregister:
1581         iio_trigger_unregister(data->trig);
1582 error_free_irq:
1583         free_irq(client->irq, indio_dev);
1584 error_uninit_buffer:
1585         iio_triggered_buffer_cleanup(indio_dev);
1586 error_regulator_disable:
1587         regulator_disable(data->vled_reg);
1588 
1589         return err;
1590 }
1591 
1592 static int gp2ap020a00f_remove(struct i2c_client *client)
1593 {
1594         struct iio_dev *indio_dev = i2c_get_clientdata(client);
1595         struct gp2ap020a00f_data *data = iio_priv(indio_dev);
1596         int err;
1597 
1598         err = gp2ap020a00f_set_operation_mode(data,
1599                                         GP2AP020A00F_OPMODE_SHUTDOWN);
1600         if (err < 0)
1601                 dev_err(&indio_dev->dev, "Failed to power off the device.\n");
1602 
1603         iio_device_unregister(indio_dev);
1604         iio_trigger_unregister(data->trig);
1605         free_irq(client->irq, indio_dev);
1606         iio_triggered_buffer_cleanup(indio_dev);
1607         regulator_disable(data->vled_reg);
1608 
1609         return 0;
1610 }
1611 
1612 static const struct i2c_device_id gp2ap020a00f_id[] = {
1613         { GP2A_I2C_NAME, 0 },
1614         { }
1615 };
1616 
1617 MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id);
1618 
1619 #ifdef CONFIG_OF
1620 static const struct of_device_id gp2ap020a00f_of_match[] = {
1621         { .compatible = "sharp,gp2ap020a00f" },
1622         { }
1623 };
1624 MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match);
1625 #endif
1626 
1627 static struct i2c_driver gp2ap020a00f_driver = {
1628         .driver = {
1629                 .name   = GP2A_I2C_NAME,
1630                 .of_match_table = of_match_ptr(gp2ap020a00f_of_match),
1631         },
1632         .probe          = gp2ap020a00f_probe,
1633         .remove         = gp2ap020a00f_remove,
1634         .id_table       = gp2ap020a00f_id,
1635 };
1636 
1637 module_i2c_driver(gp2ap020a00f_driver);
1638 
1639 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
1640 MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver");
1641 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */