cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gp2ap020a00f.c (46203B)


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