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

apds9960.c (28124B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * apds9960.c - Support for Avago APDS9960 gesture/RGB/ALS/proximity sensor
      4 *
      5 * Copyright (C) 2015, 2018
      6 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
      7 *
      8 * TODO: gesture + proximity calib offsets
      9 */
     10
     11#include <linux/acpi.h>
     12#include <linux/module.h>
     13#include <linux/init.h>
     14#include <linux/interrupt.h>
     15#include <linux/delay.h>
     16#include <linux/mutex.h>
     17#include <linux/err.h>
     18#include <linux/irq.h>
     19#include <linux/i2c.h>
     20#include <linux/pm_runtime.h>
     21#include <linux/regmap.h>
     22#include <linux/iio/iio.h>
     23#include <linux/iio/buffer.h>
     24#include <linux/iio/events.h>
     25#include <linux/iio/kfifo_buf.h>
     26#include <linux/iio/sysfs.h>
     27
     28#define APDS9960_REGMAP_NAME	"apds9960_regmap"
     29#define APDS9960_DRV_NAME	"apds9960"
     30
     31#define APDS9960_REG_RAM_START	0x00
     32#define APDS9960_REG_RAM_END	0x7f
     33
     34#define APDS9960_REG_ENABLE	0x80
     35#define APDS9960_REG_ATIME	0x81
     36#define APDS9960_REG_WTIME	0x83
     37
     38#define APDS9960_REG_AILTL	0x84
     39#define APDS9960_REG_AILTH	0x85
     40#define APDS9960_REG_AIHTL	0x86
     41#define APDS9960_REG_AIHTH	0x87
     42
     43#define APDS9960_REG_PILT	0x89
     44#define APDS9960_REG_PIHT	0x8b
     45#define APDS9960_REG_PERS	0x8c
     46
     47#define APDS9960_REG_CONFIG_1	0x8d
     48#define APDS9960_REG_PPULSE	0x8e
     49
     50#define APDS9960_REG_CONTROL	0x8f
     51#define APDS9960_REG_CONTROL_AGAIN_MASK		0x03
     52#define APDS9960_REG_CONTROL_PGAIN_MASK		0x0c
     53#define APDS9960_REG_CONTROL_AGAIN_MASK_SHIFT	0
     54#define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT	2
     55
     56#define APDS9960_REG_CONFIG_2	0x90
     57#define APDS9960_REG_CONFIG_2_GGAIN_MASK	0x60
     58#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT	5
     59
     60#define APDS9960_REG_ID		0x92
     61
     62#define APDS9960_REG_STATUS	0x93
     63#define APDS9960_REG_STATUS_PS_INT	BIT(5)
     64#define APDS9960_REG_STATUS_ALS_INT	BIT(4)
     65#define APDS9960_REG_STATUS_GINT	BIT(2)
     66
     67#define APDS9960_REG_PDATA	0x9c
     68#define APDS9960_REG_POFFSET_UR	0x9d
     69#define APDS9960_REG_POFFSET_DL 0x9e
     70#define APDS9960_REG_CONFIG_3	0x9f
     71
     72#define APDS9960_REG_GPENTH	0xa0
     73#define APDS9960_REG_GEXTH	0xa1
     74
     75#define APDS9960_REG_GCONF_1	0xa2
     76#define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK		0xc0
     77#define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT	6
     78
     79#define APDS9960_REG_GCONF_2	0xa3
     80#define APDS9960_REG_GOFFSET_U	0xa4
     81#define APDS9960_REG_GOFFSET_D	0xa5
     82#define APDS9960_REG_GPULSE	0xa6
     83#define APDS9960_REG_GOFFSET_L	0xa7
     84#define APDS9960_REG_GOFFSET_R	0xa9
     85#define APDS9960_REG_GCONF_3	0xaa
     86
     87#define APDS9960_REG_GCONF_4	0xab
     88#define APDS9960_REG_GFLVL	0xae
     89#define APDS9960_REG_GSTATUS	0xaf
     90
     91#define APDS9960_REG_IFORCE	0xe4
     92#define APDS9960_REG_PICLEAR	0xe5
     93#define APDS9960_REG_CICLEAR	0xe6
     94#define APDS9960_REG_AICLEAR	0xe7
     95
     96#define APDS9960_DEFAULT_PERS	0x33
     97#define APDS9960_DEFAULT_GPENTH	0x50
     98#define APDS9960_DEFAULT_GEXTH	0x40
     99
    100#define APDS9960_MAX_PXS_THRES_VAL	255
    101#define APDS9960_MAX_ALS_THRES_VAL	0xffff
    102#define APDS9960_MAX_INT_TIME_IN_US	1000000
    103
    104enum apds9960_als_channel_idx {
    105	IDX_ALS_CLEAR, IDX_ALS_RED, IDX_ALS_GREEN, IDX_ALS_BLUE,
    106};
    107
    108#define APDS9960_REG_ALS_BASE	0x94
    109#define APDS9960_REG_ALS_CHANNEL(_colour) \
    110	(APDS9960_REG_ALS_BASE + (IDX_ALS_##_colour * 2))
    111
    112enum apds9960_gesture_channel_idx {
    113	IDX_DIR_UP, IDX_DIR_DOWN, IDX_DIR_LEFT, IDX_DIR_RIGHT,
    114};
    115
    116#define APDS9960_REG_GFIFO_BASE	0xfc
    117#define APDS9960_REG_GFIFO_DIR(_dir) \
    118	(APDS9960_REG_GFIFO_BASE + IDX_DIR_##_dir)
    119
    120struct apds9960_data {
    121	struct i2c_client *client;
    122	struct iio_dev *indio_dev;
    123	struct mutex lock;
    124
    125	/* regmap fields */
    126	struct regmap *regmap;
    127	struct regmap_field *reg_int_als;
    128	struct regmap_field *reg_int_ges;
    129	struct regmap_field *reg_int_pxs;
    130
    131	struct regmap_field *reg_enable_als;
    132	struct regmap_field *reg_enable_ges;
    133	struct regmap_field *reg_enable_pxs;
    134
    135	/* state */
    136	int als_int;
    137	int pxs_int;
    138	int gesture_mode_running;
    139
    140	/* gain values */
    141	int als_gain;
    142	int pxs_gain;
    143
    144	/* integration time value in us */
    145	int als_adc_int_us;
    146
    147	/* gesture buffer */
    148	u8 buffer[4]; /* 4 8-bit channels */
    149};
    150
    151static const struct reg_default apds9960_reg_defaults[] = {
    152	/* Default ALS integration time = 2.48ms */
    153	{ APDS9960_REG_ATIME, 0xff },
    154};
    155
    156static const struct regmap_range apds9960_volatile_ranges[] = {
    157	regmap_reg_range(APDS9960_REG_STATUS,
    158				APDS9960_REG_PDATA),
    159	regmap_reg_range(APDS9960_REG_GFLVL,
    160				APDS9960_REG_GSTATUS),
    161	regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
    162				APDS9960_REG_GFIFO_DIR(RIGHT)),
    163	regmap_reg_range(APDS9960_REG_IFORCE,
    164				APDS9960_REG_AICLEAR),
    165};
    166
    167static const struct regmap_access_table apds9960_volatile_table = {
    168	.yes_ranges	= apds9960_volatile_ranges,
    169	.n_yes_ranges	= ARRAY_SIZE(apds9960_volatile_ranges),
    170};
    171
    172static const struct regmap_range apds9960_precious_ranges[] = {
    173	regmap_reg_range(APDS9960_REG_RAM_START, APDS9960_REG_RAM_END),
    174};
    175
    176static const struct regmap_access_table apds9960_precious_table = {
    177	.yes_ranges	= apds9960_precious_ranges,
    178	.n_yes_ranges	= ARRAY_SIZE(apds9960_precious_ranges),
    179};
    180
    181static const struct regmap_range apds9960_readable_ranges[] = {
    182	regmap_reg_range(APDS9960_REG_ENABLE,
    183				APDS9960_REG_GSTATUS),
    184	regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
    185				APDS9960_REG_GFIFO_DIR(RIGHT)),
    186};
    187
    188static const struct regmap_access_table apds9960_readable_table = {
    189	.yes_ranges	= apds9960_readable_ranges,
    190	.n_yes_ranges	= ARRAY_SIZE(apds9960_readable_ranges),
    191};
    192
    193static const struct regmap_range apds9960_writeable_ranges[] = {
    194	regmap_reg_range(APDS9960_REG_ENABLE, APDS9960_REG_CONFIG_2),
    195	regmap_reg_range(APDS9960_REG_POFFSET_UR, APDS9960_REG_GCONF_4),
    196	regmap_reg_range(APDS9960_REG_IFORCE, APDS9960_REG_AICLEAR),
    197};
    198
    199static const struct regmap_access_table apds9960_writeable_table = {
    200	.yes_ranges	= apds9960_writeable_ranges,
    201	.n_yes_ranges	= ARRAY_SIZE(apds9960_writeable_ranges),
    202};
    203
    204static const struct regmap_config apds9960_regmap_config = {
    205	.name = APDS9960_REGMAP_NAME,
    206	.reg_bits = 8,
    207	.val_bits = 8,
    208	.use_single_read = true,
    209	.use_single_write = true,
    210
    211	.volatile_table = &apds9960_volatile_table,
    212	.precious_table = &apds9960_precious_table,
    213	.rd_table = &apds9960_readable_table,
    214	.wr_table = &apds9960_writeable_table,
    215
    216	.reg_defaults = apds9960_reg_defaults,
    217	.num_reg_defaults = ARRAY_SIZE(apds9960_reg_defaults),
    218	.max_register = APDS9960_REG_GFIFO_DIR(RIGHT),
    219	.cache_type = REGCACHE_RBTREE,
    220};
    221
    222static const struct iio_event_spec apds9960_pxs_event_spec[] = {
    223	{
    224		.type = IIO_EV_TYPE_THRESH,
    225		.dir = IIO_EV_DIR_RISING,
    226		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
    227			BIT(IIO_EV_INFO_ENABLE),
    228	},
    229	{
    230		.type = IIO_EV_TYPE_THRESH,
    231		.dir = IIO_EV_DIR_FALLING,
    232		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
    233			BIT(IIO_EV_INFO_ENABLE),
    234	},
    235};
    236
    237static const struct iio_event_spec apds9960_als_event_spec[] = {
    238	{
    239		.type = IIO_EV_TYPE_THRESH,
    240		.dir = IIO_EV_DIR_RISING,
    241		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
    242			BIT(IIO_EV_INFO_ENABLE),
    243	},
    244	{
    245		.type = IIO_EV_TYPE_THRESH,
    246		.dir = IIO_EV_DIR_FALLING,
    247		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
    248			BIT(IIO_EV_INFO_ENABLE),
    249	},
    250};
    251
    252#define APDS9960_GESTURE_CHANNEL(_dir, _si) { \
    253	.type = IIO_PROXIMITY, \
    254	.channel = _si + 1, \
    255	.scan_index = _si, \
    256	.indexed = 1, \
    257	.scan_type = { \
    258		.sign = 'u', \
    259		.realbits = 8, \
    260		.storagebits = 8, \
    261	}, \
    262}
    263
    264#define APDS9960_INTENSITY_CHANNEL(_colour) { \
    265	.type = IIO_INTENSITY, \
    266	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
    267	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
    268			BIT(IIO_CHAN_INFO_INT_TIME), \
    269	.channel2 = IIO_MOD_LIGHT_##_colour, \
    270	.address = APDS9960_REG_ALS_CHANNEL(_colour), \
    271	.modified = 1, \
    272	.scan_index = -1, \
    273}
    274
    275static const unsigned long apds9960_scan_masks[] = {0xf, 0};
    276
    277static const struct iio_chan_spec apds9960_channels[] = {
    278	{
    279		.type = IIO_PROXIMITY,
    280		.address = APDS9960_REG_PDATA,
    281		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
    282		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
    283		.channel = 0,
    284		.indexed = 0,
    285		.scan_index = -1,
    286
    287		.event_spec = apds9960_pxs_event_spec,
    288		.num_event_specs = ARRAY_SIZE(apds9960_pxs_event_spec),
    289	},
    290	/* Gesture Sensor */
    291	APDS9960_GESTURE_CHANNEL(UP, 0),
    292	APDS9960_GESTURE_CHANNEL(DOWN, 1),
    293	APDS9960_GESTURE_CHANNEL(LEFT, 2),
    294	APDS9960_GESTURE_CHANNEL(RIGHT, 3),
    295	/* ALS */
    296	{
    297		.type = IIO_INTENSITY,
    298		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
    299		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
    300			BIT(IIO_CHAN_INFO_INT_TIME),
    301		.channel2 = IIO_MOD_LIGHT_CLEAR,
    302		.address = APDS9960_REG_ALS_CHANNEL(CLEAR),
    303		.modified = 1,
    304		.scan_index = -1,
    305
    306		.event_spec = apds9960_als_event_spec,
    307		.num_event_specs = ARRAY_SIZE(apds9960_als_event_spec),
    308	},
    309	/* RGB Sensor */
    310	APDS9960_INTENSITY_CHANNEL(RED),
    311	APDS9960_INTENSITY_CHANNEL(GREEN),
    312	APDS9960_INTENSITY_CHANNEL(BLUE),
    313};
    314
    315/* integration time in us */
    316static const int apds9960_int_time[][2] = {
    317	{ 28000, 246},
    318	{100000, 219},
    319	{200000, 182},
    320	{700000,   0}
    321};
    322
    323/* gain mapping */
    324static const int apds9960_pxs_gain_map[] = {1, 2, 4, 8};
    325static const int apds9960_als_gain_map[] = {1, 4, 16, 64};
    326
    327static IIO_CONST_ATTR(proximity_scale_available, "1 2 4 8");
    328static IIO_CONST_ATTR(intensity_scale_available, "1 4 16 64");
    329static IIO_CONST_ATTR_INT_TIME_AVAIL("0.028 0.1 0.2 0.7");
    330
    331static struct attribute *apds9960_attributes[] = {
    332	&iio_const_attr_proximity_scale_available.dev_attr.attr,
    333	&iio_const_attr_intensity_scale_available.dev_attr.attr,
    334	&iio_const_attr_integration_time_available.dev_attr.attr,
    335	NULL,
    336};
    337
    338static const struct attribute_group apds9960_attribute_group = {
    339	.attrs = apds9960_attributes,
    340};
    341
    342static const struct reg_field apds9960_reg_field_int_als =
    343				REG_FIELD(APDS9960_REG_ENABLE, 4, 4);
    344
    345static const struct reg_field apds9960_reg_field_int_ges =
    346				REG_FIELD(APDS9960_REG_GCONF_4, 1, 1);
    347
    348static const struct reg_field apds9960_reg_field_int_pxs =
    349				REG_FIELD(APDS9960_REG_ENABLE, 5, 5);
    350
    351static const struct reg_field apds9960_reg_field_enable_als =
    352				REG_FIELD(APDS9960_REG_ENABLE, 1, 1);
    353
    354static const struct reg_field apds9960_reg_field_enable_ges =
    355				REG_FIELD(APDS9960_REG_ENABLE, 6, 6);
    356
    357static const struct reg_field apds9960_reg_field_enable_pxs =
    358				REG_FIELD(APDS9960_REG_ENABLE, 2, 2);
    359
    360static int apds9960_set_it_time(struct apds9960_data *data, int val2)
    361{
    362	int ret = -EINVAL;
    363	int idx;
    364
    365	for (idx = 0; idx < ARRAY_SIZE(apds9960_int_time); idx++) {
    366		if (apds9960_int_time[idx][0] == val2) {
    367			mutex_lock(&data->lock);
    368			ret = regmap_write(data->regmap, APDS9960_REG_ATIME,
    369						 apds9960_int_time[idx][1]);
    370			if (!ret)
    371				data->als_adc_int_us = val2;
    372			mutex_unlock(&data->lock);
    373			break;
    374		}
    375	}
    376
    377	return ret;
    378}
    379
    380static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
    381{
    382	int ret = -EINVAL;
    383	int idx;
    384
    385	for (idx = 0; idx < ARRAY_SIZE(apds9960_pxs_gain_map); idx++) {
    386		if (apds9960_pxs_gain_map[idx] == val) {
    387			/* pxs + gesture gains are mirrored */
    388			mutex_lock(&data->lock);
    389			ret = regmap_update_bits(data->regmap,
    390				APDS9960_REG_CONTROL,
    391				APDS9960_REG_CONTROL_PGAIN_MASK,
    392				idx << APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT);
    393			if (ret) {
    394				mutex_unlock(&data->lock);
    395				break;
    396			}
    397
    398			ret = regmap_update_bits(data->regmap,
    399				APDS9960_REG_CONFIG_2,
    400				APDS9960_REG_CONFIG_2_GGAIN_MASK,
    401				idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
    402			if (!ret)
    403				data->pxs_gain = idx;
    404			mutex_unlock(&data->lock);
    405			break;
    406		}
    407	}
    408
    409	return ret;
    410}
    411
    412static int apds9960_set_als_gain(struct apds9960_data *data, int val)
    413{
    414	int ret = -EINVAL;
    415	int idx;
    416
    417	for (idx = 0; idx < ARRAY_SIZE(apds9960_als_gain_map); idx++) {
    418		if (apds9960_als_gain_map[idx] == val) {
    419			mutex_lock(&data->lock);
    420			ret = regmap_update_bits(data->regmap,
    421					APDS9960_REG_CONTROL,
    422					APDS9960_REG_CONTROL_AGAIN_MASK, idx);
    423			if (!ret)
    424				data->als_gain = idx;
    425			mutex_unlock(&data->lock);
    426			break;
    427		}
    428	}
    429
    430	return ret;
    431}
    432
    433#ifdef CONFIG_PM
    434static int apds9960_set_power_state(struct apds9960_data *data, bool on)
    435{
    436	struct device *dev = &data->client->dev;
    437	int ret = 0;
    438
    439	mutex_lock(&data->lock);
    440
    441	if (on) {
    442		int suspended;
    443
    444		suspended = pm_runtime_suspended(dev);
    445		ret = pm_runtime_get_sync(dev);
    446
    447		/* Allow one integration cycle before allowing a reading */
    448		if (suspended)
    449			usleep_range(data->als_adc_int_us,
    450				     APDS9960_MAX_INT_TIME_IN_US);
    451	} else {
    452		pm_runtime_mark_last_busy(dev);
    453		ret = pm_runtime_put_autosuspend(dev);
    454	}
    455
    456	mutex_unlock(&data->lock);
    457
    458	return ret;
    459}
    460#else
    461static int apds9960_set_power_state(struct apds9960_data *data, bool on)
    462{
    463	return 0;
    464}
    465#endif
    466
    467static int apds9960_read_raw(struct iio_dev *indio_dev,
    468			     struct iio_chan_spec const *chan,
    469			     int *val, int *val2, long mask)
    470{
    471	struct apds9960_data *data = iio_priv(indio_dev);
    472	__le16 buf;
    473	int ret = -EINVAL;
    474
    475	if (data->gesture_mode_running)
    476		return -EBUSY;
    477
    478	switch (mask) {
    479	case IIO_CHAN_INFO_RAW:
    480		apds9960_set_power_state(data, true);
    481		switch (chan->type) {
    482		case IIO_PROXIMITY:
    483			ret = regmap_read(data->regmap, chan->address, val);
    484			if (!ret)
    485				ret = IIO_VAL_INT;
    486			break;
    487		case IIO_INTENSITY:
    488			ret = regmap_bulk_read(data->regmap, chan->address,
    489					       &buf, 2);
    490			if (!ret) {
    491				ret = IIO_VAL_INT;
    492				*val = le16_to_cpu(buf);
    493			}
    494			break;
    495		default:
    496			ret = -EINVAL;
    497		}
    498		apds9960_set_power_state(data, false);
    499		break;
    500	case IIO_CHAN_INFO_INT_TIME:
    501		/* RGB + ALS sensors only have integration time */
    502		mutex_lock(&data->lock);
    503		switch (chan->type) {
    504		case IIO_INTENSITY:
    505			*val = 0;
    506			*val2 = data->als_adc_int_us;
    507			ret = IIO_VAL_INT_PLUS_MICRO;
    508			break;
    509		default:
    510			ret = -EINVAL;
    511		}
    512		mutex_unlock(&data->lock);
    513		break;
    514	case IIO_CHAN_INFO_SCALE:
    515		mutex_lock(&data->lock);
    516		switch (chan->type) {
    517		case IIO_PROXIMITY:
    518			*val = apds9960_pxs_gain_map[data->pxs_gain];
    519			ret = IIO_VAL_INT;
    520			break;
    521		case IIO_INTENSITY:
    522			*val = apds9960_als_gain_map[data->als_gain];
    523			ret = IIO_VAL_INT;
    524			break;
    525		default:
    526			ret = -EINVAL;
    527		}
    528		mutex_unlock(&data->lock);
    529		break;
    530	}
    531
    532	return ret;
    533};
    534
    535static int apds9960_write_raw(struct iio_dev *indio_dev,
    536			     struct iio_chan_spec const *chan,
    537			     int val, int val2, long mask)
    538{
    539	struct apds9960_data *data = iio_priv(indio_dev);
    540
    541	switch (mask) {
    542	case IIO_CHAN_INFO_INT_TIME:
    543		/* RGB + ALS sensors only have int time */
    544		switch (chan->type) {
    545		case IIO_INTENSITY:
    546			if (val != 0)
    547				return -EINVAL;
    548			return apds9960_set_it_time(data, val2);
    549		default:
    550			return -EINVAL;
    551		}
    552	case IIO_CHAN_INFO_SCALE:
    553		if (val2 != 0)
    554			return -EINVAL;
    555		switch (chan->type) {
    556		case IIO_PROXIMITY:
    557			return apds9960_set_pxs_gain(data, val);
    558		case IIO_INTENSITY:
    559			return apds9960_set_als_gain(data, val);
    560		default:
    561			return -EINVAL;
    562		}
    563	default:
    564		return -EINVAL;
    565	}
    566
    567	return 0;
    568}
    569
    570static inline int apds9960_get_thres_reg(const struct iio_chan_spec *chan,
    571					 enum iio_event_direction dir,
    572					 u8 *reg)
    573{
    574	switch (dir) {
    575	case IIO_EV_DIR_RISING:
    576		switch (chan->type) {
    577		case IIO_PROXIMITY:
    578			*reg = APDS9960_REG_PIHT;
    579			break;
    580		case IIO_INTENSITY:
    581			*reg = APDS9960_REG_AIHTL;
    582			break;
    583		default:
    584			return -EINVAL;
    585		}
    586		break;
    587	case IIO_EV_DIR_FALLING:
    588		switch (chan->type) {
    589		case IIO_PROXIMITY:
    590			*reg = APDS9960_REG_PILT;
    591			break;
    592		case IIO_INTENSITY:
    593			*reg = APDS9960_REG_AILTL;
    594			break;
    595		default:
    596			return -EINVAL;
    597		}
    598		break;
    599	default:
    600		return -EINVAL;
    601	}
    602
    603	return 0;
    604}
    605
    606static int apds9960_read_event(struct iio_dev *indio_dev,
    607			       const struct iio_chan_spec *chan,
    608			       enum iio_event_type type,
    609			       enum iio_event_direction dir,
    610			       enum iio_event_info info,
    611			       int *val, int *val2)
    612{
    613	u8 reg;
    614	__le16 buf;
    615	int ret = 0;
    616	struct apds9960_data *data = iio_priv(indio_dev);
    617
    618	if (info != IIO_EV_INFO_VALUE)
    619		return -EINVAL;
    620
    621	ret = apds9960_get_thres_reg(chan, dir, &reg);
    622	if (ret < 0)
    623		return ret;
    624
    625	if (chan->type == IIO_PROXIMITY) {
    626		ret = regmap_read(data->regmap, reg, val);
    627		if (ret < 0)
    628			return ret;
    629	} else if (chan->type == IIO_INTENSITY) {
    630		ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
    631		if (ret < 0)
    632			return ret;
    633		*val = le16_to_cpu(buf);
    634	} else
    635		return -EINVAL;
    636
    637	*val2 = 0;
    638
    639	return IIO_VAL_INT;
    640}
    641
    642static int apds9960_write_event(struct iio_dev *indio_dev,
    643				const struct iio_chan_spec *chan,
    644				enum iio_event_type type,
    645				enum iio_event_direction dir,
    646				enum iio_event_info info,
    647				int val, int val2)
    648{
    649	u8 reg;
    650	__le16 buf;
    651	int ret = 0;
    652	struct apds9960_data *data = iio_priv(indio_dev);
    653
    654	if (info != IIO_EV_INFO_VALUE)
    655		return -EINVAL;
    656
    657	ret = apds9960_get_thres_reg(chan, dir, &reg);
    658	if (ret < 0)
    659		return ret;
    660
    661	if (chan->type == IIO_PROXIMITY) {
    662		if (val < 0 || val > APDS9960_MAX_PXS_THRES_VAL)
    663			return -EINVAL;
    664		ret = regmap_write(data->regmap, reg, val);
    665		if (ret < 0)
    666			return ret;
    667	} else if (chan->type == IIO_INTENSITY) {
    668		if (val < 0 || val > APDS9960_MAX_ALS_THRES_VAL)
    669			return -EINVAL;
    670		buf = cpu_to_le16(val);
    671		ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
    672		if (ret < 0)
    673			return ret;
    674	} else
    675		return -EINVAL;
    676
    677	return 0;
    678}
    679
    680static int apds9960_read_event_config(struct iio_dev *indio_dev,
    681				      const struct iio_chan_spec *chan,
    682				      enum iio_event_type type,
    683				      enum iio_event_direction dir)
    684{
    685	struct apds9960_data *data = iio_priv(indio_dev);
    686
    687	switch (chan->type) {
    688	case IIO_PROXIMITY:
    689		return data->pxs_int;
    690	case IIO_INTENSITY:
    691		return data->als_int;
    692	default:
    693		return -EINVAL;
    694	}
    695
    696	return 0;
    697}
    698
    699static int apds9960_write_event_config(struct iio_dev *indio_dev,
    700				       const struct iio_chan_spec *chan,
    701				       enum iio_event_type type,
    702				       enum iio_event_direction dir,
    703				       int state)
    704{
    705	struct apds9960_data *data = iio_priv(indio_dev);
    706	int ret;
    707
    708	state = !!state;
    709
    710	switch (chan->type) {
    711	case IIO_PROXIMITY:
    712		if (data->pxs_int == state)
    713			return -EINVAL;
    714
    715		ret = regmap_field_write(data->reg_int_pxs, state);
    716		if (ret)
    717			return ret;
    718		data->pxs_int = state;
    719		apds9960_set_power_state(data, state);
    720		break;
    721	case IIO_INTENSITY:
    722		if (data->als_int == state)
    723			return -EINVAL;
    724
    725		ret = regmap_field_write(data->reg_int_als, state);
    726		if (ret)
    727			return ret;
    728		data->als_int = state;
    729		apds9960_set_power_state(data, state);
    730		break;
    731	default:
    732		return -EINVAL;
    733	}
    734
    735	return 0;
    736}
    737
    738static const struct iio_info apds9960_info = {
    739	.attrs = &apds9960_attribute_group,
    740	.read_raw = apds9960_read_raw,
    741	.write_raw = apds9960_write_raw,
    742	.read_event_value = apds9960_read_event,
    743	.write_event_value = apds9960_write_event,
    744	.read_event_config = apds9960_read_event_config,
    745	.write_event_config = apds9960_write_event_config,
    746
    747};
    748
    749static inline int apds9660_fifo_is_empty(struct apds9960_data *data)
    750{
    751	int cnt;
    752	int ret;
    753
    754	ret = regmap_read(data->regmap, APDS9960_REG_GFLVL, &cnt);
    755	if (ret)
    756		return ret;
    757
    758	return cnt;
    759}
    760
    761static void apds9960_read_gesture_fifo(struct apds9960_data *data)
    762{
    763	int ret, cnt = 0;
    764
    765	mutex_lock(&data->lock);
    766	data->gesture_mode_running = 1;
    767
    768	while (cnt || (cnt = apds9660_fifo_is_empty(data) > 0)) {
    769		ret = regmap_bulk_read(data->regmap, APDS9960_REG_GFIFO_BASE,
    770				      &data->buffer, 4);
    771
    772		if (ret)
    773			goto err_read;
    774
    775		iio_push_to_buffers(data->indio_dev, data->buffer);
    776		cnt--;
    777	}
    778
    779err_read:
    780	data->gesture_mode_running = 0;
    781	mutex_unlock(&data->lock);
    782}
    783
    784static irqreturn_t apds9960_interrupt_handler(int irq, void *private)
    785{
    786	struct iio_dev *indio_dev = private;
    787	struct apds9960_data *data = iio_priv(indio_dev);
    788	int ret, status;
    789
    790	ret = regmap_read(data->regmap, APDS9960_REG_STATUS, &status);
    791	if (ret < 0) {
    792		dev_err(&data->client->dev, "irq status reg read failed\n");
    793		return IRQ_HANDLED;
    794	}
    795
    796	if ((status & APDS9960_REG_STATUS_ALS_INT) && data->als_int) {
    797		iio_push_event(indio_dev,
    798			       IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
    799						    IIO_EV_TYPE_THRESH,
    800						    IIO_EV_DIR_EITHER),
    801			       iio_get_time_ns(indio_dev));
    802		regmap_write(data->regmap, APDS9960_REG_CICLEAR, 1);
    803	}
    804
    805	if ((status & APDS9960_REG_STATUS_PS_INT) && data->pxs_int) {
    806		iio_push_event(indio_dev,
    807			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
    808						    IIO_EV_TYPE_THRESH,
    809						    IIO_EV_DIR_EITHER),
    810			       iio_get_time_ns(indio_dev));
    811		regmap_write(data->regmap, APDS9960_REG_PICLEAR, 1);
    812	}
    813
    814	if (status & APDS9960_REG_STATUS_GINT)
    815		apds9960_read_gesture_fifo(data);
    816
    817	return IRQ_HANDLED;
    818}
    819
    820static int apds9960_set_powermode(struct apds9960_data *data, bool state)
    821{
    822	return regmap_update_bits(data->regmap, APDS9960_REG_ENABLE, 1, state);
    823}
    824
    825static int apds9960_buffer_postenable(struct iio_dev *indio_dev)
    826{
    827	struct apds9960_data *data = iio_priv(indio_dev);
    828	int ret;
    829
    830	ret = regmap_field_write(data->reg_int_ges, 1);
    831	if (ret)
    832		return ret;
    833
    834	ret = regmap_field_write(data->reg_enable_ges, 1);
    835	if (ret)
    836		return ret;
    837
    838	pm_runtime_get_sync(&data->client->dev);
    839
    840	return 0;
    841}
    842
    843static int apds9960_buffer_predisable(struct iio_dev *indio_dev)
    844{
    845	struct apds9960_data *data = iio_priv(indio_dev);
    846	int ret;
    847
    848	ret = regmap_field_write(data->reg_enable_ges, 0);
    849	if (ret)
    850		return ret;
    851
    852	ret = regmap_field_write(data->reg_int_ges, 0);
    853	if (ret)
    854		return ret;
    855
    856	pm_runtime_put_autosuspend(&data->client->dev);
    857
    858	return 0;
    859}
    860
    861static const struct iio_buffer_setup_ops apds9960_buffer_setup_ops = {
    862	.postenable = apds9960_buffer_postenable,
    863	.predisable = apds9960_buffer_predisable,
    864};
    865
    866static int apds9960_regfield_init(struct apds9960_data *data)
    867{
    868	struct device *dev = &data->client->dev;
    869	struct regmap *regmap = data->regmap;
    870
    871	data->reg_int_als = devm_regmap_field_alloc(dev, regmap,
    872						apds9960_reg_field_int_als);
    873	if (IS_ERR(data->reg_int_als)) {
    874		dev_err(dev, "INT ALS reg field init failed\n");
    875		return PTR_ERR(data->reg_int_als);
    876	}
    877
    878	data->reg_int_ges = devm_regmap_field_alloc(dev, regmap,
    879						apds9960_reg_field_int_ges);
    880	if (IS_ERR(data->reg_int_ges)) {
    881		dev_err(dev, "INT gesture reg field init failed\n");
    882		return PTR_ERR(data->reg_int_ges);
    883	}
    884
    885	data->reg_int_pxs = devm_regmap_field_alloc(dev, regmap,
    886						apds9960_reg_field_int_pxs);
    887	if (IS_ERR(data->reg_int_pxs)) {
    888		dev_err(dev, "INT pxs reg field init failed\n");
    889		return PTR_ERR(data->reg_int_pxs);
    890	}
    891
    892	data->reg_enable_als = devm_regmap_field_alloc(dev, regmap,
    893						apds9960_reg_field_enable_als);
    894	if (IS_ERR(data->reg_enable_als)) {
    895		dev_err(dev, "Enable ALS reg field init failed\n");
    896		return PTR_ERR(data->reg_enable_als);
    897	}
    898
    899	data->reg_enable_ges = devm_regmap_field_alloc(dev, regmap,
    900						apds9960_reg_field_enable_ges);
    901	if (IS_ERR(data->reg_enable_ges)) {
    902		dev_err(dev, "Enable gesture reg field init failed\n");
    903		return PTR_ERR(data->reg_enable_ges);
    904	}
    905
    906	data->reg_enable_pxs = devm_regmap_field_alloc(dev, regmap,
    907						apds9960_reg_field_enable_pxs);
    908	if (IS_ERR(data->reg_enable_pxs)) {
    909		dev_err(dev, "Enable PXS reg field init failed\n");
    910		return PTR_ERR(data->reg_enable_pxs);
    911	}
    912
    913	return 0;
    914}
    915
    916static int apds9960_chip_init(struct apds9960_data *data)
    917{
    918	int ret;
    919
    920	/* Default IT for ALS of 28 ms */
    921	ret = apds9960_set_it_time(data, 28000);
    922	if (ret)
    923		return ret;
    924
    925	/* Ensure gesture interrupt is OFF */
    926	ret = regmap_field_write(data->reg_int_ges, 0);
    927	if (ret)
    928		return ret;
    929
    930	/* Disable gesture sensor, since polling is useless from user-space */
    931	ret = regmap_field_write(data->reg_enable_ges, 0);
    932	if (ret)
    933		return ret;
    934
    935	/* Ensure proximity interrupt is OFF */
    936	ret = regmap_field_write(data->reg_int_pxs, 0);
    937	if (ret)
    938		return ret;
    939
    940	/* Enable proximity sensor for polling */
    941	ret = regmap_field_write(data->reg_enable_pxs, 1);
    942	if (ret)
    943		return ret;
    944
    945	/* Ensure ALS interrupt is OFF */
    946	ret = regmap_field_write(data->reg_int_als, 0);
    947	if (ret)
    948		return ret;
    949
    950	/* Enable ALS sensor for polling */
    951	ret = regmap_field_write(data->reg_enable_als, 1);
    952	if (ret)
    953		return ret;
    954	/*
    955	 * When enabled trigger an interrupt after 3 readings
    956	 * outside threshold for ALS + PXS
    957	 */
    958	ret = regmap_write(data->regmap, APDS9960_REG_PERS,
    959			   APDS9960_DEFAULT_PERS);
    960	if (ret)
    961		return ret;
    962
    963	/*
    964	 * Wait for 4 event outside gesture threshold to prevent interrupt
    965	 * flooding.
    966	 */
    967	ret = regmap_update_bits(data->regmap, APDS9960_REG_GCONF_1,
    968			APDS9960_REG_GCONF_1_GFIFO_THRES_MASK,
    969			BIT(0) << APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT);
    970	if (ret)
    971		return ret;
    972
    973	/* Default ENTER and EXIT thresholds for the GESTURE engine. */
    974	ret = regmap_write(data->regmap, APDS9960_REG_GPENTH,
    975			   APDS9960_DEFAULT_GPENTH);
    976	if (ret)
    977		return ret;
    978
    979	ret = regmap_write(data->regmap, APDS9960_REG_GEXTH,
    980			   APDS9960_DEFAULT_GEXTH);
    981	if (ret)
    982		return ret;
    983
    984	return apds9960_set_powermode(data, 1);
    985}
    986
    987static int apds9960_probe(struct i2c_client *client,
    988			  const struct i2c_device_id *id)
    989{
    990	struct apds9960_data *data;
    991	struct iio_dev *indio_dev;
    992	int ret;
    993
    994	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
    995	if (!indio_dev)
    996		return -ENOMEM;
    997
    998	indio_dev->info = &apds9960_info;
    999	indio_dev->name = APDS9960_DRV_NAME;
   1000	indio_dev->channels = apds9960_channels;
   1001	indio_dev->num_channels = ARRAY_SIZE(apds9960_channels);
   1002	indio_dev->available_scan_masks = apds9960_scan_masks;
   1003	indio_dev->modes = INDIO_DIRECT_MODE;
   1004
   1005	ret = devm_iio_kfifo_buffer_setup(&client->dev, indio_dev,
   1006					  &apds9960_buffer_setup_ops);
   1007	if (ret)
   1008		return ret;
   1009
   1010	data = iio_priv(indio_dev);
   1011	i2c_set_clientdata(client, indio_dev);
   1012
   1013	data->regmap = devm_regmap_init_i2c(client, &apds9960_regmap_config);
   1014	if (IS_ERR(data->regmap)) {
   1015		dev_err(&client->dev, "regmap initialization failed.\n");
   1016		return PTR_ERR(data->regmap);
   1017	}
   1018
   1019	data->client = client;
   1020	data->indio_dev = indio_dev;
   1021	mutex_init(&data->lock);
   1022
   1023	ret = pm_runtime_set_active(&client->dev);
   1024	if (ret)
   1025		goto error_power_down;
   1026
   1027	pm_runtime_enable(&client->dev);
   1028	pm_runtime_set_autosuspend_delay(&client->dev, 5000);
   1029	pm_runtime_use_autosuspend(&client->dev);
   1030
   1031	apds9960_set_power_state(data, true);
   1032
   1033	ret = apds9960_regfield_init(data);
   1034	if (ret)
   1035		goto error_power_down;
   1036
   1037	ret = apds9960_chip_init(data);
   1038	if (ret)
   1039		goto error_power_down;
   1040
   1041	if (client->irq <= 0) {
   1042		dev_err(&client->dev, "no valid irq defined\n");
   1043		ret = -EINVAL;
   1044		goto error_power_down;
   1045	}
   1046	ret = devm_request_threaded_irq(&client->dev, client->irq,
   1047					NULL, apds9960_interrupt_handler,
   1048					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
   1049					"apds9960_event",
   1050					indio_dev);
   1051	if (ret) {
   1052		dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
   1053		goto error_power_down;
   1054	}
   1055
   1056	ret = iio_device_register(indio_dev);
   1057	if (ret)
   1058		goto error_power_down;
   1059
   1060	apds9960_set_power_state(data, false);
   1061
   1062	return 0;
   1063
   1064error_power_down:
   1065	apds9960_set_power_state(data, false);
   1066
   1067	return ret;
   1068}
   1069
   1070static int apds9960_remove(struct i2c_client *client)
   1071{
   1072	struct iio_dev *indio_dev = i2c_get_clientdata(client);
   1073	struct apds9960_data *data = iio_priv(indio_dev);
   1074
   1075	iio_device_unregister(indio_dev);
   1076	pm_runtime_disable(&client->dev);
   1077	pm_runtime_set_suspended(&client->dev);
   1078	apds9960_set_powermode(data, 0);
   1079
   1080	return 0;
   1081}
   1082
   1083#ifdef CONFIG_PM
   1084static int apds9960_runtime_suspend(struct device *dev)
   1085{
   1086	struct apds9960_data *data =
   1087			iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
   1088
   1089	return apds9960_set_powermode(data, 0);
   1090}
   1091
   1092static int apds9960_runtime_resume(struct device *dev)
   1093{
   1094	struct apds9960_data *data =
   1095			iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
   1096
   1097	return apds9960_set_powermode(data, 1);
   1098}
   1099#endif
   1100
   1101static const struct dev_pm_ops apds9960_pm_ops = {
   1102	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
   1103				pm_runtime_force_resume)
   1104	SET_RUNTIME_PM_OPS(apds9960_runtime_suspend,
   1105			   apds9960_runtime_resume, NULL)
   1106};
   1107
   1108static const struct i2c_device_id apds9960_id[] = {
   1109	{ "apds9960", 0 },
   1110	{}
   1111};
   1112MODULE_DEVICE_TABLE(i2c, apds9960_id);
   1113
   1114static const struct acpi_device_id apds9960_acpi_match[] = {
   1115	{ "MSHW0184" },
   1116	{ }
   1117};
   1118MODULE_DEVICE_TABLE(acpi, apds9960_acpi_match);
   1119
   1120static const struct of_device_id apds9960_of_match[] = {
   1121	{ .compatible = "avago,apds9960" },
   1122	{ }
   1123};
   1124MODULE_DEVICE_TABLE(of, apds9960_of_match);
   1125
   1126static struct i2c_driver apds9960_driver = {
   1127	.driver = {
   1128		.name	= APDS9960_DRV_NAME,
   1129		.of_match_table = apds9960_of_match,
   1130		.pm	= &apds9960_pm_ops,
   1131		.acpi_match_table = apds9960_acpi_match,
   1132	},
   1133	.probe		= apds9960_probe,
   1134	.remove		= apds9960_remove,
   1135	.id_table	= apds9960_id,
   1136};
   1137module_i2c_driver(apds9960_driver);
   1138
   1139MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
   1140MODULE_DESCRIPTION("APDS9960 Gesture/RGB/ALS/Proximity sensor");
   1141MODULE_LICENSE("GPL");