0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <linux/debugfs.h>
0035 #include <linux/delay.h>
0036 #include <linux/i2c.h>
0037 #include <linux/interrupt.h>
0038 #include <linux/irq.h>
0039 #include <linux/irq_work.h>
0040 #include <linux/module.h>
0041 #include <linux/mod_devicetable.h>
0042 #include <linux/mutex.h>
0043 #include <linux/regmap.h>
0044 #include <linux/regulator/consumer.h>
0045 #include <linux/slab.h>
0046 #include <asm/unaligned.h>
0047 #include <linux/iio/buffer.h>
0048 #include <linux/iio/events.h>
0049 #include <linux/iio/iio.h>
0050 #include <linux/iio/sysfs.h>
0051 #include <linux/iio/trigger.h>
0052 #include <linux/iio/trigger_consumer.h>
0053 #include <linux/iio/triggered_buffer.h>
0054
0055 #define GP2A_I2C_NAME "gp2ap020a00f"
0056
0057
0058 #define GP2AP020A00F_OP_REG 0x00
0059 #define GP2AP020A00F_ALS_REG 0x01
0060 #define GP2AP020A00F_PS_REG 0x02
0061 #define GP2AP020A00F_LED_REG 0x03
0062 #define GP2AP020A00F_TL_L_REG 0x04
0063 #define GP2AP020A00F_TL_H_REG 0x05
0064 #define GP2AP020A00F_TH_L_REG 0x06
0065 #define GP2AP020A00F_TH_H_REG 0x07
0066 #define GP2AP020A00F_PL_L_REG 0x08
0067 #define GP2AP020A00F_PL_H_REG 0x09
0068 #define GP2AP020A00F_PH_L_REG 0x0a
0069 #define GP2AP020A00F_PH_H_REG 0x0b
0070 #define GP2AP020A00F_D0_L_REG 0x0c
0071 #define GP2AP020A00F_D0_H_REG 0x0d
0072 #define GP2AP020A00F_D1_L_REG 0x0e
0073 #define GP2AP020A00F_D1_H_REG 0x0f
0074 #define GP2AP020A00F_D2_L_REG 0x10
0075 #define GP2AP020A00F_D2_H_REG 0x11
0076 #define GP2AP020A00F_NUM_REGS 0x12
0077
0078
0079 #define GP2AP020A00F_OP3_MASK 0x80
0080 #define GP2AP020A00F_OP3_SHUTDOWN 0x00
0081 #define GP2AP020A00F_OP3_OPERATION 0x80
0082 #define GP2AP020A00F_OP2_MASK 0x40
0083 #define GP2AP020A00F_OP2_AUTO_SHUTDOWN 0x00
0084 #define GP2AP020A00F_OP2_CONT_OPERATION 0x40
0085 #define GP2AP020A00F_OP_MASK 0x30
0086 #define GP2AP020A00F_OP_ALS_AND_PS 0x00
0087 #define GP2AP020A00F_OP_ALS 0x10
0088 #define GP2AP020A00F_OP_PS 0x20
0089 #define GP2AP020A00F_OP_DEBUG 0x30
0090 #define GP2AP020A00F_PROX_MASK 0x08
0091 #define GP2AP020A00F_PROX_NON_DETECT 0x00
0092 #define GP2AP020A00F_PROX_DETECT 0x08
0093 #define GP2AP020A00F_FLAG_P 0x04
0094 #define GP2AP020A00F_FLAG_A 0x02
0095 #define GP2AP020A00F_TYPE_MASK 0x01
0096 #define GP2AP020A00F_TYPE_MANUAL_CALC 0x00
0097 #define GP2AP020A00F_TYPE_AUTO_CALC 0x01
0098
0099
0100 #define GP2AP020A00F_PRST_MASK 0xc0
0101 #define GP2AP020A00F_PRST_ONCE 0x00
0102 #define GP2AP020A00F_PRST_4_CYCLES 0x40
0103 #define GP2AP020A00F_PRST_8_CYCLES 0x80
0104 #define GP2AP020A00F_PRST_16_CYCLES 0xc0
0105 #define GP2AP020A00F_RES_A_MASK 0x38
0106 #define GP2AP020A00F_RES_A_800ms 0x00
0107 #define GP2AP020A00F_RES_A_400ms 0x08
0108 #define GP2AP020A00F_RES_A_200ms 0x10
0109 #define GP2AP020A00F_RES_A_100ms 0x18
0110 #define GP2AP020A00F_RES_A_25ms 0x20
0111 #define GP2AP020A00F_RES_A_6_25ms 0x28
0112 #define GP2AP020A00F_RES_A_1_56ms 0x30
0113 #define GP2AP020A00F_RES_A_0_39ms 0x38
0114 #define GP2AP020A00F_RANGE_A_MASK 0x07
0115 #define GP2AP020A00F_RANGE_A_x1 0x00
0116 #define GP2AP020A00F_RANGE_A_x2 0x01
0117 #define GP2AP020A00F_RANGE_A_x4 0x02
0118 #define GP2AP020A00F_RANGE_A_x8 0x03
0119 #define GP2AP020A00F_RANGE_A_x16 0x04
0120 #define GP2AP020A00F_RANGE_A_x32 0x05
0121 #define GP2AP020A00F_RANGE_A_x64 0x06
0122 #define GP2AP020A00F_RANGE_A_x128 0x07
0123
0124
0125 #define GP2AP020A00F_ALC_MASK 0x80
0126 #define GP2AP020A00F_ALC_ON 0x80
0127 #define GP2AP020A00F_ALC_OFF 0x00
0128 #define GP2AP020A00F_INTTYPE_MASK 0x40
0129 #define GP2AP020A00F_INTTYPE_LEVEL 0x00
0130 #define GP2AP020A00F_INTTYPE_PULSE 0x40
0131 #define GP2AP020A00F_RES_P_MASK 0x38
0132 #define GP2AP020A00F_RES_P_800ms_x2 0x00
0133 #define GP2AP020A00F_RES_P_400ms_x2 0x08
0134 #define GP2AP020A00F_RES_P_200ms_x2 0x10
0135 #define GP2AP020A00F_RES_P_100ms_x2 0x18
0136 #define GP2AP020A00F_RES_P_25ms_x2 0x20
0137 #define GP2AP020A00F_RES_P_6_25ms_x2 0x28
0138 #define GP2AP020A00F_RES_P_1_56ms_x2 0x30
0139 #define GP2AP020A00F_RES_P_0_39ms_x2 0x38
0140 #define GP2AP020A00F_RANGE_P_MASK 0x07
0141 #define GP2AP020A00F_RANGE_P_x1 0x00
0142 #define GP2AP020A00F_RANGE_P_x2 0x01
0143 #define GP2AP020A00F_RANGE_P_x4 0x02
0144 #define GP2AP020A00F_RANGE_P_x8 0x03
0145 #define GP2AP020A00F_RANGE_P_x16 0x04
0146 #define GP2AP020A00F_RANGE_P_x32 0x05
0147 #define GP2AP020A00F_RANGE_P_x64 0x06
0148 #define GP2AP020A00F_RANGE_P_x128 0x07
0149
0150
0151 #define GP2AP020A00F_INTVAL_MASK 0xc0
0152 #define GP2AP020A00F_INTVAL_0 0x00
0153 #define GP2AP020A00F_INTVAL_4 0x40
0154 #define GP2AP020A00F_INTVAL_8 0x80
0155 #define GP2AP020A00F_INTVAL_16 0xc0
0156 #define GP2AP020A00F_IS_MASK 0x30
0157 #define GP2AP020A00F_IS_13_8mA 0x00
0158 #define GP2AP020A00F_IS_27_5mA 0x10
0159 #define GP2AP020A00F_IS_55mA 0x20
0160 #define GP2AP020A00F_IS_110mA 0x30
0161 #define GP2AP020A00F_PIN_MASK 0x0c
0162 #define GP2AP020A00F_PIN_ALS_OR_PS 0x00
0163 #define GP2AP020A00F_PIN_ALS 0x04
0164 #define GP2AP020A00F_PIN_PS 0x08
0165 #define GP2AP020A00F_PIN_PS_DETECT 0x0c
0166 #define GP2AP020A00F_FREQ_MASK 0x02
0167 #define GP2AP020A00F_FREQ_327_5kHz 0x00
0168 #define GP2AP020A00F_FREQ_81_8kHz 0x02
0169 #define GP2AP020A00F_RST 0x01
0170
0171 #define GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR 0
0172 #define GP2AP020A00F_SCAN_MODE_LIGHT_IR 1
0173 #define GP2AP020A00F_SCAN_MODE_PROXIMITY 2
0174 #define GP2AP020A00F_CHAN_TIMESTAMP 3
0175
0176 #define GP2AP020A00F_DATA_READY_TIMEOUT msecs_to_jiffies(1000)
0177 #define GP2AP020A00F_DATA_REG(chan) (GP2AP020A00F_D0_L_REG + \
0178 (chan) * 2)
0179 #define GP2AP020A00F_THRESH_REG(th_val_id) (GP2AP020A00F_TL_L_REG + \
0180 (th_val_id) * 2)
0181 #define GP2AP020A00F_THRESH_VAL_ID(reg_addr) ((reg_addr - 4) / 2)
0182
0183 #define GP2AP020A00F_SUBTRACT_MODE 0
0184 #define GP2AP020A00F_ADD_MODE 1
0185
0186 #define GP2AP020A00F_MAX_CHANNELS 3
0187
0188 enum gp2ap020a00f_opmode {
0189 GP2AP020A00F_OPMODE_READ_RAW_CLEAR,
0190 GP2AP020A00F_OPMODE_READ_RAW_IR,
0191 GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY,
0192 GP2AP020A00F_OPMODE_ALS,
0193 GP2AP020A00F_OPMODE_PS,
0194 GP2AP020A00F_OPMODE_ALS_AND_PS,
0195 GP2AP020A00F_OPMODE_PROX_DETECT,
0196 GP2AP020A00F_OPMODE_SHUTDOWN,
0197 GP2AP020A00F_NUM_OPMODES,
0198 };
0199
0200 enum gp2ap020a00f_cmd {
0201 GP2AP020A00F_CMD_READ_RAW_CLEAR,
0202 GP2AP020A00F_CMD_READ_RAW_IR,
0203 GP2AP020A00F_CMD_READ_RAW_PROXIMITY,
0204 GP2AP020A00F_CMD_TRIGGER_CLEAR_EN,
0205 GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS,
0206 GP2AP020A00F_CMD_TRIGGER_IR_EN,
0207 GP2AP020A00F_CMD_TRIGGER_IR_DIS,
0208 GP2AP020A00F_CMD_TRIGGER_PROX_EN,
0209 GP2AP020A00F_CMD_TRIGGER_PROX_DIS,
0210 GP2AP020A00F_CMD_ALS_HIGH_EV_EN,
0211 GP2AP020A00F_CMD_ALS_HIGH_EV_DIS,
0212 GP2AP020A00F_CMD_ALS_LOW_EV_EN,
0213 GP2AP020A00F_CMD_ALS_LOW_EV_DIS,
0214 GP2AP020A00F_CMD_PROX_HIGH_EV_EN,
0215 GP2AP020A00F_CMD_PROX_HIGH_EV_DIS,
0216 GP2AP020A00F_CMD_PROX_LOW_EV_EN,
0217 GP2AP020A00F_CMD_PROX_LOW_EV_DIS,
0218 };
0219
0220 enum gp2ap020a00f_flags {
0221 GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER,
0222 GP2AP020A00F_FLAG_ALS_IR_TRIGGER,
0223 GP2AP020A00F_FLAG_PROX_TRIGGER,
0224 GP2AP020A00F_FLAG_PROX_RISING_EV,
0225 GP2AP020A00F_FLAG_PROX_FALLING_EV,
0226 GP2AP020A00F_FLAG_ALS_RISING_EV,
0227 GP2AP020A00F_FLAG_ALS_FALLING_EV,
0228 GP2AP020A00F_FLAG_LUX_MODE_HI,
0229 GP2AP020A00F_FLAG_DATA_READY,
0230 };
0231
0232 enum gp2ap020a00f_thresh_val_id {
0233 GP2AP020A00F_THRESH_TL,
0234 GP2AP020A00F_THRESH_TH,
0235 GP2AP020A00F_THRESH_PL,
0236 GP2AP020A00F_THRESH_PH,
0237 };
0238
0239 struct gp2ap020a00f_data {
0240 const struct gp2ap020a00f_platform_data *pdata;
0241 struct i2c_client *client;
0242 struct mutex lock;
0243 char *buffer;
0244 struct regulator *vled_reg;
0245 unsigned long flags;
0246 enum gp2ap020a00f_opmode cur_opmode;
0247 struct iio_trigger *trig;
0248 struct regmap *regmap;
0249 unsigned int thresh_val[4];
0250 u8 debug_reg_addr;
0251 struct irq_work work;
0252 wait_queue_head_t data_ready_queue;
0253 };
0254
0255 static const u8 gp2ap020a00f_reg_init_tab[] = {
0256 [GP2AP020A00F_OP_REG] = GP2AP020A00F_OP3_SHUTDOWN,
0257 [GP2AP020A00F_ALS_REG] = GP2AP020A00F_RES_A_25ms |
0258 GP2AP020A00F_RANGE_A_x8,
0259 [GP2AP020A00F_PS_REG] = GP2AP020A00F_ALC_ON |
0260 GP2AP020A00F_RES_P_1_56ms_x2 |
0261 GP2AP020A00F_RANGE_P_x4,
0262 [GP2AP020A00F_LED_REG] = GP2AP020A00F_INTVAL_0 |
0263 GP2AP020A00F_IS_110mA |
0264 GP2AP020A00F_FREQ_327_5kHz,
0265 [GP2AP020A00F_TL_L_REG] = 0,
0266 [GP2AP020A00F_TL_H_REG] = 0,
0267 [GP2AP020A00F_TH_L_REG] = 0,
0268 [GP2AP020A00F_TH_H_REG] = 0,
0269 [GP2AP020A00F_PL_L_REG] = 0,
0270 [GP2AP020A00F_PL_H_REG] = 0,
0271 [GP2AP020A00F_PH_L_REG] = 0,
0272 [GP2AP020A00F_PH_H_REG] = 0,
0273 };
0274
0275 static bool gp2ap020a00f_is_volatile_reg(struct device *dev, unsigned int reg)
0276 {
0277 switch (reg) {
0278 case GP2AP020A00F_OP_REG:
0279 case GP2AP020A00F_D0_L_REG:
0280 case GP2AP020A00F_D0_H_REG:
0281 case GP2AP020A00F_D1_L_REG:
0282 case GP2AP020A00F_D1_H_REG:
0283 case GP2AP020A00F_D2_L_REG:
0284 case GP2AP020A00F_D2_H_REG:
0285 return true;
0286 default:
0287 return false;
0288 }
0289 }
0290
0291 static const struct regmap_config gp2ap020a00f_regmap_config = {
0292 .reg_bits = 8,
0293 .val_bits = 8,
0294
0295 .max_register = GP2AP020A00F_D2_H_REG,
0296 .cache_type = REGCACHE_RBTREE,
0297
0298 .volatile_reg = gp2ap020a00f_is_volatile_reg,
0299 };
0300
0301 static const struct gp2ap020a00f_mutable_config_regs {
0302 u8 op_reg;
0303 u8 als_reg;
0304 u8 ps_reg;
0305 u8 led_reg;
0306 } opmode_regs_settings[GP2AP020A00F_NUM_OPMODES] = {
0307 [GP2AP020A00F_OPMODE_READ_RAW_CLEAR] = {
0308 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
0309 | GP2AP020A00F_OP3_OPERATION
0310 | GP2AP020A00F_TYPE_AUTO_CALC,
0311 GP2AP020A00F_PRST_ONCE,
0312 GP2AP020A00F_INTTYPE_LEVEL,
0313 GP2AP020A00F_PIN_ALS
0314 },
0315 [GP2AP020A00F_OPMODE_READ_RAW_IR] = {
0316 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
0317 | GP2AP020A00F_OP3_OPERATION
0318 | GP2AP020A00F_TYPE_MANUAL_CALC,
0319 GP2AP020A00F_PRST_ONCE,
0320 GP2AP020A00F_INTTYPE_LEVEL,
0321 GP2AP020A00F_PIN_ALS
0322 },
0323 [GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY] = {
0324 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
0325 | GP2AP020A00F_OP3_OPERATION
0326 | GP2AP020A00F_TYPE_MANUAL_CALC,
0327 GP2AP020A00F_PRST_ONCE,
0328 GP2AP020A00F_INTTYPE_LEVEL,
0329 GP2AP020A00F_PIN_PS
0330 },
0331 [GP2AP020A00F_OPMODE_PROX_DETECT] = {
0332 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
0333 | GP2AP020A00F_OP3_OPERATION
0334 | GP2AP020A00F_TYPE_MANUAL_CALC,
0335 GP2AP020A00F_PRST_4_CYCLES,
0336 GP2AP020A00F_INTTYPE_PULSE,
0337 GP2AP020A00F_PIN_PS_DETECT
0338 },
0339 [GP2AP020A00F_OPMODE_ALS] = {
0340 GP2AP020A00F_OP_ALS | GP2AP020A00F_OP2_CONT_OPERATION
0341 | GP2AP020A00F_OP3_OPERATION
0342 | GP2AP020A00F_TYPE_AUTO_CALC,
0343 GP2AP020A00F_PRST_ONCE,
0344 GP2AP020A00F_INTTYPE_LEVEL,
0345 GP2AP020A00F_PIN_ALS
0346 },
0347 [GP2AP020A00F_OPMODE_PS] = {
0348 GP2AP020A00F_OP_PS | GP2AP020A00F_OP2_CONT_OPERATION
0349 | GP2AP020A00F_OP3_OPERATION
0350 | GP2AP020A00F_TYPE_MANUAL_CALC,
0351 GP2AP020A00F_PRST_4_CYCLES,
0352 GP2AP020A00F_INTTYPE_LEVEL,
0353 GP2AP020A00F_PIN_PS
0354 },
0355 [GP2AP020A00F_OPMODE_ALS_AND_PS] = {
0356 GP2AP020A00F_OP_ALS_AND_PS
0357 | GP2AP020A00F_OP2_CONT_OPERATION
0358 | GP2AP020A00F_OP3_OPERATION
0359 | GP2AP020A00F_TYPE_AUTO_CALC,
0360 GP2AP020A00F_PRST_4_CYCLES,
0361 GP2AP020A00F_INTTYPE_LEVEL,
0362 GP2AP020A00F_PIN_ALS_OR_PS
0363 },
0364 [GP2AP020A00F_OPMODE_SHUTDOWN] = { GP2AP020A00F_OP3_SHUTDOWN, },
0365 };
0366
0367 static int gp2ap020a00f_set_operation_mode(struct gp2ap020a00f_data *data,
0368 enum gp2ap020a00f_opmode op)
0369 {
0370 unsigned int op_reg_val;
0371 int err;
0372
0373 if (op != GP2AP020A00F_OPMODE_SHUTDOWN) {
0374 err = regmap_read(data->regmap, GP2AP020A00F_OP_REG,
0375 &op_reg_val);
0376 if (err < 0)
0377 return err;
0378
0379
0380
0381
0382 if ((opmode_regs_settings[op].op_reg & GP2AP020A00F_OP_MASK) !=
0383 (op_reg_val & GP2AP020A00F_OP_MASK)) {
0384
0385 err = regmap_update_bits(data->regmap,
0386 GP2AP020A00F_OP_REG, GP2AP020A00F_OP3_MASK,
0387 GP2AP020A00F_OP3_SHUTDOWN);
0388 if (err < 0)
0389 return err;
0390 }
0391
0392 err = regmap_update_bits(data->regmap, GP2AP020A00F_ALS_REG,
0393 GP2AP020A00F_PRST_MASK, opmode_regs_settings[op]
0394 .als_reg);
0395 if (err < 0)
0396 return err;
0397
0398 err = regmap_update_bits(data->regmap, GP2AP020A00F_PS_REG,
0399 GP2AP020A00F_INTTYPE_MASK, opmode_regs_settings[op]
0400 .ps_reg);
0401 if (err < 0)
0402 return err;
0403
0404 err = regmap_update_bits(data->regmap, GP2AP020A00F_LED_REG,
0405 GP2AP020A00F_PIN_MASK, opmode_regs_settings[op]
0406 .led_reg);
0407 if (err < 0)
0408 return err;
0409 }
0410
0411
0412 err = regmap_update_bits(data->regmap,
0413 GP2AP020A00F_OP_REG,
0414 GP2AP020A00F_OP_MASK | GP2AP020A00F_OP2_MASK |
0415 GP2AP020A00F_OP3_MASK | GP2AP020A00F_TYPE_MASK,
0416 opmode_regs_settings[op].op_reg);
0417 if (err < 0)
0418 return err;
0419
0420 data->cur_opmode = op;
0421
0422 return 0;
0423 }
0424
0425 static bool gp2ap020a00f_als_enabled(struct gp2ap020a00f_data *data)
0426 {
0427 return test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags) ||
0428 test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags) ||
0429 test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags) ||
0430 test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
0431 }
0432
0433 static bool gp2ap020a00f_prox_detect_enabled(struct gp2ap020a00f_data *data)
0434 {
0435 return test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags) ||
0436 test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
0437 }
0438
0439 static int gp2ap020a00f_write_event_threshold(struct gp2ap020a00f_data *data,
0440 enum gp2ap020a00f_thresh_val_id th_val_id,
0441 bool enable)
0442 {
0443 __le16 thresh_buf = 0;
0444 unsigned int thresh_reg_val;
0445
0446 if (!enable)
0447 thresh_reg_val = 0;
0448 else if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags) &&
0449 th_val_id != GP2AP020A00F_THRESH_PL &&
0450 th_val_id != GP2AP020A00F_THRESH_PH)
0451
0452
0453
0454
0455 thresh_reg_val = data->thresh_val[th_val_id] / 16;
0456 else
0457 thresh_reg_val = data->thresh_val[th_val_id] > 16000 ?
0458 16000 :
0459 data->thresh_val[th_val_id];
0460
0461 thresh_buf = cpu_to_le16(thresh_reg_val);
0462
0463 return regmap_bulk_write(data->regmap,
0464 GP2AP020A00F_THRESH_REG(th_val_id),
0465 (u8 *)&thresh_buf, 2);
0466 }
0467
0468 static int gp2ap020a00f_alter_opmode(struct gp2ap020a00f_data *data,
0469 enum gp2ap020a00f_opmode diff_mode, int add_sub)
0470 {
0471 enum gp2ap020a00f_opmode new_mode;
0472
0473 if (diff_mode != GP2AP020A00F_OPMODE_ALS &&
0474 diff_mode != GP2AP020A00F_OPMODE_PS)
0475 return -EINVAL;
0476
0477 if (add_sub == GP2AP020A00F_ADD_MODE) {
0478 if (data->cur_opmode == GP2AP020A00F_OPMODE_SHUTDOWN)
0479 new_mode = diff_mode;
0480 else
0481 new_mode = GP2AP020A00F_OPMODE_ALS_AND_PS;
0482 } else {
0483 if (data->cur_opmode == GP2AP020A00F_OPMODE_ALS_AND_PS)
0484 new_mode = (diff_mode == GP2AP020A00F_OPMODE_ALS) ?
0485 GP2AP020A00F_OPMODE_PS :
0486 GP2AP020A00F_OPMODE_ALS;
0487 else
0488 new_mode = GP2AP020A00F_OPMODE_SHUTDOWN;
0489 }
0490
0491 return gp2ap020a00f_set_operation_mode(data, new_mode);
0492 }
0493
0494 static int gp2ap020a00f_exec_cmd(struct gp2ap020a00f_data *data,
0495 enum gp2ap020a00f_cmd cmd)
0496 {
0497 int err = 0;
0498
0499 switch (cmd) {
0500 case GP2AP020A00F_CMD_READ_RAW_CLEAR:
0501 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
0502 return -EBUSY;
0503 err = gp2ap020a00f_set_operation_mode(data,
0504 GP2AP020A00F_OPMODE_READ_RAW_CLEAR);
0505 break;
0506 case GP2AP020A00F_CMD_READ_RAW_IR:
0507 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
0508 return -EBUSY;
0509 err = gp2ap020a00f_set_operation_mode(data,
0510 GP2AP020A00F_OPMODE_READ_RAW_IR);
0511 break;
0512 case GP2AP020A00F_CMD_READ_RAW_PROXIMITY:
0513 if (data->cur_opmode != GP2AP020A00F_OPMODE_SHUTDOWN)
0514 return -EBUSY;
0515 err = gp2ap020a00f_set_operation_mode(data,
0516 GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY);
0517 break;
0518 case GP2AP020A00F_CMD_TRIGGER_CLEAR_EN:
0519 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
0520 return -EBUSY;
0521 if (!gp2ap020a00f_als_enabled(data))
0522 err = gp2ap020a00f_alter_opmode(data,
0523 GP2AP020A00F_OPMODE_ALS,
0524 GP2AP020A00F_ADD_MODE);
0525 set_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
0526 break;
0527 case GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS:
0528 clear_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &data->flags);
0529 if (gp2ap020a00f_als_enabled(data))
0530 break;
0531 err = gp2ap020a00f_alter_opmode(data,
0532 GP2AP020A00F_OPMODE_ALS,
0533 GP2AP020A00F_SUBTRACT_MODE);
0534 break;
0535 case GP2AP020A00F_CMD_TRIGGER_IR_EN:
0536 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
0537 return -EBUSY;
0538 if (!gp2ap020a00f_als_enabled(data))
0539 err = gp2ap020a00f_alter_opmode(data,
0540 GP2AP020A00F_OPMODE_ALS,
0541 GP2AP020A00F_ADD_MODE);
0542 set_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
0543 break;
0544 case GP2AP020A00F_CMD_TRIGGER_IR_DIS:
0545 clear_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &data->flags);
0546 if (gp2ap020a00f_als_enabled(data))
0547 break;
0548 err = gp2ap020a00f_alter_opmode(data,
0549 GP2AP020A00F_OPMODE_ALS,
0550 GP2AP020A00F_SUBTRACT_MODE);
0551 break;
0552 case GP2AP020A00F_CMD_TRIGGER_PROX_EN:
0553 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
0554 return -EBUSY;
0555 err = gp2ap020a00f_alter_opmode(data,
0556 GP2AP020A00F_OPMODE_PS,
0557 GP2AP020A00F_ADD_MODE);
0558 set_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
0559 break;
0560 case GP2AP020A00F_CMD_TRIGGER_PROX_DIS:
0561 clear_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &data->flags);
0562 err = gp2ap020a00f_alter_opmode(data,
0563 GP2AP020A00F_OPMODE_PS,
0564 GP2AP020A00F_SUBTRACT_MODE);
0565 break;
0566 case GP2AP020A00F_CMD_ALS_HIGH_EV_EN:
0567 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
0568 return 0;
0569 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
0570 return -EBUSY;
0571 if (!gp2ap020a00f_als_enabled(data)) {
0572 err = gp2ap020a00f_alter_opmode(data,
0573 GP2AP020A00F_OPMODE_ALS,
0574 GP2AP020A00F_ADD_MODE);
0575 if (err < 0)
0576 return err;
0577 }
0578 set_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
0579 err = gp2ap020a00f_write_event_threshold(data,
0580 GP2AP020A00F_THRESH_TH, true);
0581 break;
0582 case GP2AP020A00F_CMD_ALS_HIGH_EV_DIS:
0583 if (!test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags))
0584 return 0;
0585 clear_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags);
0586 if (!gp2ap020a00f_als_enabled(data)) {
0587 err = gp2ap020a00f_alter_opmode(data,
0588 GP2AP020A00F_OPMODE_ALS,
0589 GP2AP020A00F_SUBTRACT_MODE);
0590 if (err < 0)
0591 return err;
0592 }
0593 err = gp2ap020a00f_write_event_threshold(data,
0594 GP2AP020A00F_THRESH_TH, false);
0595 break;
0596 case GP2AP020A00F_CMD_ALS_LOW_EV_EN:
0597 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
0598 return 0;
0599 if (data->cur_opmode == GP2AP020A00F_OPMODE_PROX_DETECT)
0600 return -EBUSY;
0601 if (!gp2ap020a00f_als_enabled(data)) {
0602 err = gp2ap020a00f_alter_opmode(data,
0603 GP2AP020A00F_OPMODE_ALS,
0604 GP2AP020A00F_ADD_MODE);
0605 if (err < 0)
0606 return err;
0607 }
0608 set_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
0609 err = gp2ap020a00f_write_event_threshold(data,
0610 GP2AP020A00F_THRESH_TL, true);
0611 break;
0612 case GP2AP020A00F_CMD_ALS_LOW_EV_DIS:
0613 if (!test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags))
0614 return 0;
0615 clear_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags);
0616 if (!gp2ap020a00f_als_enabled(data)) {
0617 err = gp2ap020a00f_alter_opmode(data,
0618 GP2AP020A00F_OPMODE_ALS,
0619 GP2AP020A00F_SUBTRACT_MODE);
0620 if (err < 0)
0621 return err;
0622 }
0623 err = gp2ap020a00f_write_event_threshold(data,
0624 GP2AP020A00F_THRESH_TL, false);
0625 break;
0626 case GP2AP020A00F_CMD_PROX_HIGH_EV_EN:
0627 if (test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
0628 return 0;
0629 if (gp2ap020a00f_als_enabled(data) ||
0630 data->cur_opmode == GP2AP020A00F_OPMODE_PS)
0631 return -EBUSY;
0632 if (!gp2ap020a00f_prox_detect_enabled(data)) {
0633 err = gp2ap020a00f_set_operation_mode(data,
0634 GP2AP020A00F_OPMODE_PROX_DETECT);
0635 if (err < 0)
0636 return err;
0637 }
0638 set_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
0639 err = gp2ap020a00f_write_event_threshold(data,
0640 GP2AP020A00F_THRESH_PH, true);
0641 break;
0642 case GP2AP020A00F_CMD_PROX_HIGH_EV_DIS:
0643 if (!test_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags))
0644 return 0;
0645 clear_bit(GP2AP020A00F_FLAG_PROX_RISING_EV, &data->flags);
0646 err = gp2ap020a00f_set_operation_mode(data,
0647 GP2AP020A00F_OPMODE_SHUTDOWN);
0648 if (err < 0)
0649 return err;
0650 err = gp2ap020a00f_write_event_threshold(data,
0651 GP2AP020A00F_THRESH_PH, false);
0652 break;
0653 case GP2AP020A00F_CMD_PROX_LOW_EV_EN:
0654 if (test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
0655 return 0;
0656 if (gp2ap020a00f_als_enabled(data) ||
0657 data->cur_opmode == GP2AP020A00F_OPMODE_PS)
0658 return -EBUSY;
0659 if (!gp2ap020a00f_prox_detect_enabled(data)) {
0660 err = gp2ap020a00f_set_operation_mode(data,
0661 GP2AP020A00F_OPMODE_PROX_DETECT);
0662 if (err < 0)
0663 return err;
0664 }
0665 set_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
0666 err = gp2ap020a00f_write_event_threshold(data,
0667 GP2AP020A00F_THRESH_PL, true);
0668 break;
0669 case GP2AP020A00F_CMD_PROX_LOW_EV_DIS:
0670 if (!test_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags))
0671 return 0;
0672 clear_bit(GP2AP020A00F_FLAG_PROX_FALLING_EV, &data->flags);
0673 err = gp2ap020a00f_set_operation_mode(data,
0674 GP2AP020A00F_OPMODE_SHUTDOWN);
0675 if (err < 0)
0676 return err;
0677 err = gp2ap020a00f_write_event_threshold(data,
0678 GP2AP020A00F_THRESH_PL, false);
0679 break;
0680 }
0681
0682 return err;
0683 }
0684
0685 static int wait_conversion_complete_irq(struct gp2ap020a00f_data *data)
0686 {
0687 int ret;
0688
0689 ret = wait_event_timeout(data->data_ready_queue,
0690 test_bit(GP2AP020A00F_FLAG_DATA_READY,
0691 &data->flags),
0692 GP2AP020A00F_DATA_READY_TIMEOUT);
0693 clear_bit(GP2AP020A00F_FLAG_DATA_READY, &data->flags);
0694
0695 return ret > 0 ? 0 : -ETIME;
0696 }
0697
0698 static int gp2ap020a00f_read_output(struct gp2ap020a00f_data *data,
0699 unsigned int output_reg, int *val)
0700 {
0701 u8 reg_buf[2];
0702 int err;
0703
0704 err = wait_conversion_complete_irq(data);
0705 if (err < 0)
0706 dev_dbg(&data->client->dev, "data ready timeout\n");
0707
0708 err = regmap_bulk_read(data->regmap, output_reg, reg_buf, 2);
0709 if (err < 0)
0710 return err;
0711
0712 *val = le16_to_cpup((__le16 *)reg_buf);
0713
0714 return err;
0715 }
0716
0717 static bool gp2ap020a00f_adjust_lux_mode(struct gp2ap020a00f_data *data,
0718 int output_val)
0719 {
0720 u8 new_range = 0xff;
0721 int err;
0722
0723 if (!test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags)) {
0724 if (output_val > 16000) {
0725 set_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
0726 new_range = GP2AP020A00F_RANGE_A_x128;
0727 }
0728 } else {
0729 if (output_val < 1000) {
0730 clear_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags);
0731 new_range = GP2AP020A00F_RANGE_A_x8;
0732 }
0733 }
0734
0735 if (new_range != 0xff) {
0736
0737
0738
0739 err = gp2ap020a00f_write_event_threshold(data,
0740 GP2AP020A00F_THRESH_TH, false);
0741 if (err < 0) {
0742 dev_err(&data->client->dev,
0743 "Clearing als threshold register failed.\n");
0744 return false;
0745 }
0746
0747 err = gp2ap020a00f_write_event_threshold(data,
0748 GP2AP020A00F_THRESH_TL, false);
0749 if (err < 0) {
0750 dev_err(&data->client->dev,
0751 "Clearing als threshold register failed.\n");
0752 return false;
0753 }
0754
0755
0756 err = regmap_update_bits(data->regmap,
0757 GP2AP020A00F_OP_REG,
0758 GP2AP020A00F_OP3_MASK,
0759 GP2AP020A00F_OP3_SHUTDOWN);
0760
0761 if (err < 0) {
0762 dev_err(&data->client->dev,
0763 "Shutting down the device failed.\n");
0764 return false;
0765 }
0766
0767 err = regmap_update_bits(data->regmap,
0768 GP2AP020A00F_ALS_REG,
0769 GP2AP020A00F_RANGE_A_MASK,
0770 new_range);
0771
0772 if (err < 0) {
0773 dev_err(&data->client->dev,
0774 "Adjusting device lux mode failed.\n");
0775 return false;
0776 }
0777
0778 err = regmap_update_bits(data->regmap,
0779 GP2AP020A00F_OP_REG,
0780 GP2AP020A00F_OP3_MASK,
0781 GP2AP020A00F_OP3_OPERATION);
0782
0783 if (err < 0) {
0784 dev_err(&data->client->dev,
0785 "Powering up the device failed.\n");
0786 return false;
0787 }
0788
0789
0790 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &data->flags)) {
0791 err = gp2ap020a00f_write_event_threshold(data,
0792 GP2AP020A00F_THRESH_TH, true);
0793 if (err < 0) {
0794 dev_err(&data->client->dev,
0795 "Adjusting als threshold value failed.\n");
0796 return false;
0797 }
0798 }
0799
0800 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &data->flags)) {
0801 err = gp2ap020a00f_write_event_threshold(data,
0802 GP2AP020A00F_THRESH_TL, true);
0803 if (err < 0) {
0804 dev_err(&data->client->dev,
0805 "Adjusting als threshold value failed.\n");
0806 return false;
0807 }
0808 }
0809
0810 return true;
0811 }
0812
0813 return false;
0814 }
0815
0816 static void gp2ap020a00f_output_to_lux(struct gp2ap020a00f_data *data,
0817 int *output_val)
0818 {
0819 if (test_bit(GP2AP020A00F_FLAG_LUX_MODE_HI, &data->flags))
0820 *output_val *= 16;
0821 }
0822
0823 static void gp2ap020a00f_iio_trigger_work(struct irq_work *work)
0824 {
0825 struct gp2ap020a00f_data *data =
0826 container_of(work, struct gp2ap020a00f_data, work);
0827
0828 iio_trigger_poll(data->trig);
0829 }
0830
0831 static irqreturn_t gp2ap020a00f_prox_sensing_handler(int irq, void *data)
0832 {
0833 struct iio_dev *indio_dev = data;
0834 struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
0835 unsigned int op_reg_val;
0836 int ret;
0837
0838
0839 ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG, &op_reg_val);
0840 if (ret < 0)
0841 return IRQ_HANDLED;
0842
0843 if (gp2ap020a00f_prox_detect_enabled(priv)) {
0844 if (op_reg_val & GP2AP020A00F_PROX_DETECT) {
0845 iio_push_event(indio_dev,
0846 IIO_UNMOD_EVENT_CODE(
0847 IIO_PROXIMITY,
0848 GP2AP020A00F_SCAN_MODE_PROXIMITY,
0849 IIO_EV_TYPE_ROC,
0850 IIO_EV_DIR_RISING),
0851 iio_get_time_ns(indio_dev));
0852 } else {
0853 iio_push_event(indio_dev,
0854 IIO_UNMOD_EVENT_CODE(
0855 IIO_PROXIMITY,
0856 GP2AP020A00F_SCAN_MODE_PROXIMITY,
0857 IIO_EV_TYPE_ROC,
0858 IIO_EV_DIR_FALLING),
0859 iio_get_time_ns(indio_dev));
0860 }
0861 }
0862
0863 return IRQ_HANDLED;
0864 }
0865
0866 static irqreturn_t gp2ap020a00f_thresh_event_handler(int irq, void *data)
0867 {
0868 struct iio_dev *indio_dev = data;
0869 struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
0870 u8 op_reg_flags, d0_reg_buf[2];
0871 unsigned int output_val, op_reg_val;
0872 int thresh_val_id, ret;
0873
0874
0875 ret = regmap_read(priv->regmap, GP2AP020A00F_OP_REG,
0876 &op_reg_val);
0877 if (ret < 0)
0878 goto done;
0879
0880 op_reg_flags = op_reg_val & (GP2AP020A00F_FLAG_A | GP2AP020A00F_FLAG_P
0881 | GP2AP020A00F_PROX_DETECT);
0882
0883 op_reg_val &= (~GP2AP020A00F_FLAG_A & ~GP2AP020A00F_FLAG_P
0884 & ~GP2AP020A00F_PROX_DETECT);
0885
0886
0887 if (priv->cur_opmode != GP2AP020A00F_OPMODE_PROX_DETECT) {
0888 ret = regmap_write(priv->regmap, GP2AP020A00F_OP_REG,
0889 op_reg_val);
0890 if (ret < 0)
0891 goto done;
0892 }
0893
0894 if (op_reg_flags & GP2AP020A00F_FLAG_A) {
0895
0896
0897
0898 ret = regmap_bulk_read(priv->regmap, GP2AP020A00F_D0_L_REG,
0899 d0_reg_buf, 2);
0900 if (ret < 0)
0901 goto done;
0902
0903 output_val = le16_to_cpup((__le16 *)d0_reg_buf);
0904
0905 if (gp2ap020a00f_adjust_lux_mode(priv, output_val))
0906 goto done;
0907
0908 gp2ap020a00f_output_to_lux(priv, &output_val);
0909
0910
0911
0912
0913
0914 if (test_bit(GP2AP020A00F_FLAG_ALS_RISING_EV, &priv->flags)) {
0915 thresh_val_id =
0916 GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TH_L_REG);
0917 if (output_val > priv->thresh_val[thresh_val_id])
0918 iio_push_event(indio_dev,
0919 IIO_MOD_EVENT_CODE(
0920 IIO_LIGHT,
0921 GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
0922 IIO_MOD_LIGHT_CLEAR,
0923 IIO_EV_TYPE_THRESH,
0924 IIO_EV_DIR_RISING),
0925 iio_get_time_ns(indio_dev));
0926 }
0927
0928 if (test_bit(GP2AP020A00F_FLAG_ALS_FALLING_EV, &priv->flags)) {
0929 thresh_val_id =
0930 GP2AP020A00F_THRESH_VAL_ID(GP2AP020A00F_TL_L_REG);
0931 if (output_val < priv->thresh_val[thresh_val_id])
0932 iio_push_event(indio_dev,
0933 IIO_MOD_EVENT_CODE(
0934 IIO_LIGHT,
0935 GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR,
0936 IIO_MOD_LIGHT_CLEAR,
0937 IIO_EV_TYPE_THRESH,
0938 IIO_EV_DIR_FALLING),
0939 iio_get_time_ns(indio_dev));
0940 }
0941 }
0942
0943 if (priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_CLEAR ||
0944 priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_IR ||
0945 priv->cur_opmode == GP2AP020A00F_OPMODE_READ_RAW_PROXIMITY) {
0946 set_bit(GP2AP020A00F_FLAG_DATA_READY, &priv->flags);
0947 wake_up(&priv->data_ready_queue);
0948 goto done;
0949 }
0950
0951 if (test_bit(GP2AP020A00F_FLAG_ALS_CLEAR_TRIGGER, &priv->flags) ||
0952 test_bit(GP2AP020A00F_FLAG_ALS_IR_TRIGGER, &priv->flags) ||
0953 test_bit(GP2AP020A00F_FLAG_PROX_TRIGGER, &priv->flags))
0954
0955 irq_work_queue(&priv->work);
0956
0957 done:
0958 return IRQ_HANDLED;
0959 }
0960
0961 static irqreturn_t gp2ap020a00f_trigger_handler(int irq, void *data)
0962 {
0963 struct iio_poll_func *pf = data;
0964 struct iio_dev *indio_dev = pf->indio_dev;
0965 struct gp2ap020a00f_data *priv = iio_priv(indio_dev);
0966 size_t d_size = 0;
0967 int i, out_val, ret;
0968
0969 for_each_set_bit(i, indio_dev->active_scan_mask,
0970 indio_dev->masklength) {
0971 ret = regmap_bulk_read(priv->regmap,
0972 GP2AP020A00F_DATA_REG(i),
0973 &priv->buffer[d_size], 2);
0974 if (ret < 0)
0975 goto done;
0976
0977 if (i == GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR ||
0978 i == GP2AP020A00F_SCAN_MODE_LIGHT_IR) {
0979 out_val = le16_to_cpup((__le16 *)&priv->buffer[d_size]);
0980 gp2ap020a00f_output_to_lux(priv, &out_val);
0981
0982 put_unaligned_le32(out_val, &priv->buffer[d_size]);
0983 d_size += 4;
0984 } else {
0985 d_size += 2;
0986 }
0987 }
0988
0989 iio_push_to_buffers_with_timestamp(indio_dev, priv->buffer,
0990 pf->timestamp);
0991 done:
0992 iio_trigger_notify_done(indio_dev->trig);
0993
0994 return IRQ_HANDLED;
0995 }
0996
0997 static u8 gp2ap020a00f_get_thresh_reg(const struct iio_chan_spec *chan,
0998 enum iio_event_direction event_dir)
0999 {
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
1119
1120
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
1395
1396
1397
1398
1399
1400
1401 for_each_set_bit(i, indio_dev->active_scan_mask,
1402 indio_dev->masklength) {
1403 switch (i) {
1404 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
1405 err = gp2ap020a00f_exec_cmd(data,
1406 GP2AP020A00F_CMD_TRIGGER_CLEAR_EN);
1407 break;
1408 case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
1409 err = gp2ap020a00f_exec_cmd(data,
1410 GP2AP020A00F_CMD_TRIGGER_IR_EN);
1411 break;
1412 case GP2AP020A00F_SCAN_MODE_PROXIMITY:
1413 err = gp2ap020a00f_exec_cmd(data,
1414 GP2AP020A00F_CMD_TRIGGER_PROX_EN);
1415 break;
1416 }
1417 }
1418
1419 if (err < 0)
1420 goto error_unlock;
1421
1422 data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
1423 if (!data->buffer)
1424 err = -ENOMEM;
1425
1426 error_unlock:
1427 mutex_unlock(&data->lock);
1428
1429 return err;
1430 }
1431
1432 static int gp2ap020a00f_buffer_predisable(struct iio_dev *indio_dev)
1433 {
1434 struct gp2ap020a00f_data *data = iio_priv(indio_dev);
1435 int i, err = 0;
1436
1437 mutex_lock(&data->lock);
1438
1439 for_each_set_bit(i, indio_dev->active_scan_mask,
1440 indio_dev->masklength) {
1441 switch (i) {
1442 case GP2AP020A00F_SCAN_MODE_LIGHT_CLEAR:
1443 err = gp2ap020a00f_exec_cmd(data,
1444 GP2AP020A00F_CMD_TRIGGER_CLEAR_DIS);
1445 break;
1446 case GP2AP020A00F_SCAN_MODE_LIGHT_IR:
1447 err = gp2ap020a00f_exec_cmd(data,
1448 GP2AP020A00F_CMD_TRIGGER_IR_DIS);
1449 break;
1450 case GP2AP020A00F_SCAN_MODE_PROXIMITY:
1451 err = gp2ap020a00f_exec_cmd(data,
1452 GP2AP020A00F_CMD_TRIGGER_PROX_DIS);
1453 break;
1454 }
1455 }
1456
1457 if (err == 0)
1458 kfree(data->buffer);
1459
1460 mutex_unlock(&data->lock);
1461
1462 return err;
1463 }
1464
1465 static const struct iio_buffer_setup_ops gp2ap020a00f_buffer_setup_ops = {
1466 .postenable = &gp2ap020a00f_buffer_postenable,
1467 .predisable = &gp2ap020a00f_buffer_predisable,
1468 };
1469
1470 static 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
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
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
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
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
1564 error_trigger_unregister:
1565 iio_trigger_unregister(data->trig);
1566 error_free_irq:
1567 free_irq(client->irq, indio_dev);
1568 error_uninit_buffer:
1569 iio_triggered_buffer_cleanup(indio_dev);
1570 error_regulator_disable:
1571 regulator_disable(data->vled_reg);
1572
1573 return err;
1574 }
1575
1576 static 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
1596 static const struct i2c_device_id gp2ap020a00f_id[] = {
1597 { GP2A_I2C_NAME, 0 },
1598 { }
1599 };
1600
1601 MODULE_DEVICE_TABLE(i2c, gp2ap020a00f_id);
1602
1603 static const struct of_device_id gp2ap020a00f_of_match[] = {
1604 { .compatible = "sharp,gp2ap020a00f" },
1605 { }
1606 };
1607 MODULE_DEVICE_TABLE(of, gp2ap020a00f_of_match);
1608
1609 static 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
1619 module_i2c_driver(gp2ap020a00f_driver);
1620
1621 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
1622 MODULE_DESCRIPTION("Sharp GP2AP020A00F Proximity/ALS sensor driver");
1623 MODULE_LICENSE("GPL v2");