Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * apds9960.c - Support for Avago APDS9960 gesture/RGB/ALS/proximity sensor
0004  *
0005  * Copyright (C) 2015, 2018
0006  * Author: Matt Ranostay <matt.ranostay@konsulko.com>
0007  *
0008  * TODO: gesture + proximity calib offsets
0009  */
0010 
0011 #include <linux/acpi.h>
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/delay.h>
0016 #include <linux/mutex.h>
0017 #include <linux/err.h>
0018 #include <linux/irq.h>
0019 #include <linux/i2c.h>
0020 #include <linux/pm_runtime.h>
0021 #include <linux/regmap.h>
0022 #include <linux/iio/iio.h>
0023 #include <linux/iio/buffer.h>
0024 #include <linux/iio/events.h>
0025 #include <linux/iio/kfifo_buf.h>
0026 #include <linux/iio/sysfs.h>
0027 
0028 #define APDS9960_REGMAP_NAME    "apds9960_regmap"
0029 #define APDS9960_DRV_NAME   "apds9960"
0030 
0031 #define APDS9960_REG_RAM_START  0x00
0032 #define APDS9960_REG_RAM_END    0x7f
0033 
0034 #define APDS9960_REG_ENABLE 0x80
0035 #define APDS9960_REG_ATIME  0x81
0036 #define APDS9960_REG_WTIME  0x83
0037 
0038 #define APDS9960_REG_AILTL  0x84
0039 #define APDS9960_REG_AILTH  0x85
0040 #define APDS9960_REG_AIHTL  0x86
0041 #define APDS9960_REG_AIHTH  0x87
0042 
0043 #define APDS9960_REG_PILT   0x89
0044 #define APDS9960_REG_PIHT   0x8b
0045 #define APDS9960_REG_PERS   0x8c
0046 
0047 #define APDS9960_REG_CONFIG_1   0x8d
0048 #define APDS9960_REG_PPULSE 0x8e
0049 
0050 #define APDS9960_REG_CONTROL    0x8f
0051 #define APDS9960_REG_CONTROL_AGAIN_MASK     0x03
0052 #define APDS9960_REG_CONTROL_PGAIN_MASK     0x0c
0053 #define APDS9960_REG_CONTROL_AGAIN_MASK_SHIFT   0
0054 #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT   2
0055 
0056 #define APDS9960_REG_CONFIG_2   0x90
0057 #define APDS9960_REG_CONFIG_2_GGAIN_MASK    0x60
0058 #define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT  5
0059 
0060 #define APDS9960_REG_ID     0x92
0061 
0062 #define APDS9960_REG_STATUS 0x93
0063 #define APDS9960_REG_STATUS_PS_INT  BIT(5)
0064 #define APDS9960_REG_STATUS_ALS_INT BIT(4)
0065 #define APDS9960_REG_STATUS_GINT    BIT(2)
0066 
0067 #define APDS9960_REG_PDATA  0x9c
0068 #define APDS9960_REG_POFFSET_UR 0x9d
0069 #define APDS9960_REG_POFFSET_DL 0x9e
0070 #define APDS9960_REG_CONFIG_3   0x9f
0071 
0072 #define APDS9960_REG_GPENTH 0xa0
0073 #define APDS9960_REG_GEXTH  0xa1
0074 
0075 #define APDS9960_REG_GCONF_1    0xa2
0076 #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK       0xc0
0077 #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6
0078 
0079 #define APDS9960_REG_GCONF_2    0xa3
0080 #define APDS9960_REG_GOFFSET_U  0xa4
0081 #define APDS9960_REG_GOFFSET_D  0xa5
0082 #define APDS9960_REG_GPULSE 0xa6
0083 #define APDS9960_REG_GOFFSET_L  0xa7
0084 #define APDS9960_REG_GOFFSET_R  0xa9
0085 #define APDS9960_REG_GCONF_3    0xaa
0086 
0087 #define APDS9960_REG_GCONF_4    0xab
0088 #define APDS9960_REG_GFLVL  0xae
0089 #define APDS9960_REG_GSTATUS    0xaf
0090 
0091 #define APDS9960_REG_IFORCE 0xe4
0092 #define APDS9960_REG_PICLEAR    0xe5
0093 #define APDS9960_REG_CICLEAR    0xe6
0094 #define APDS9960_REG_AICLEAR    0xe7
0095 
0096 #define APDS9960_DEFAULT_PERS   0x33
0097 #define APDS9960_DEFAULT_GPENTH 0x50
0098 #define APDS9960_DEFAULT_GEXTH  0x40
0099 
0100 #define APDS9960_MAX_PXS_THRES_VAL  255
0101 #define APDS9960_MAX_ALS_THRES_VAL  0xffff
0102 #define APDS9960_MAX_INT_TIME_IN_US 1000000
0103 
0104 enum apds9960_als_channel_idx {
0105     IDX_ALS_CLEAR, IDX_ALS_RED, IDX_ALS_GREEN, IDX_ALS_BLUE,
0106 };
0107 
0108 #define APDS9960_REG_ALS_BASE   0x94
0109 #define APDS9960_REG_ALS_CHANNEL(_colour) \
0110     (APDS9960_REG_ALS_BASE + (IDX_ALS_##_colour * 2))
0111 
0112 enum apds9960_gesture_channel_idx {
0113     IDX_DIR_UP, IDX_DIR_DOWN, IDX_DIR_LEFT, IDX_DIR_RIGHT,
0114 };
0115 
0116 #define APDS9960_REG_GFIFO_BASE 0xfc
0117 #define APDS9960_REG_GFIFO_DIR(_dir) \
0118     (APDS9960_REG_GFIFO_BASE + IDX_DIR_##_dir)
0119 
0120 struct apds9960_data {
0121     struct i2c_client *client;
0122     struct iio_dev *indio_dev;
0123     struct mutex lock;
0124 
0125     /* regmap fields */
0126     struct regmap *regmap;
0127     struct regmap_field *reg_int_als;
0128     struct regmap_field *reg_int_ges;
0129     struct regmap_field *reg_int_pxs;
0130 
0131     struct regmap_field *reg_enable_als;
0132     struct regmap_field *reg_enable_ges;
0133     struct regmap_field *reg_enable_pxs;
0134 
0135     /* state */
0136     int als_int;
0137     int pxs_int;
0138     int gesture_mode_running;
0139 
0140     /* gain values */
0141     int als_gain;
0142     int pxs_gain;
0143 
0144     /* integration time value in us */
0145     int als_adc_int_us;
0146 
0147     /* gesture buffer */
0148     u8 buffer[4]; /* 4 8-bit channels */
0149 };
0150 
0151 static const struct reg_default apds9960_reg_defaults[] = {
0152     /* Default ALS integration time = 2.48ms */
0153     { APDS9960_REG_ATIME, 0xff },
0154 };
0155 
0156 static const struct regmap_range apds9960_volatile_ranges[] = {
0157     regmap_reg_range(APDS9960_REG_STATUS,
0158                 APDS9960_REG_PDATA),
0159     regmap_reg_range(APDS9960_REG_GFLVL,
0160                 APDS9960_REG_GSTATUS),
0161     regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
0162                 APDS9960_REG_GFIFO_DIR(RIGHT)),
0163     regmap_reg_range(APDS9960_REG_IFORCE,
0164                 APDS9960_REG_AICLEAR),
0165 };
0166 
0167 static const struct regmap_access_table apds9960_volatile_table = {
0168     .yes_ranges = apds9960_volatile_ranges,
0169     .n_yes_ranges   = ARRAY_SIZE(apds9960_volatile_ranges),
0170 };
0171 
0172 static const struct regmap_range apds9960_precious_ranges[] = {
0173     regmap_reg_range(APDS9960_REG_RAM_START, APDS9960_REG_RAM_END),
0174 };
0175 
0176 static const struct regmap_access_table apds9960_precious_table = {
0177     .yes_ranges = apds9960_precious_ranges,
0178     .n_yes_ranges   = ARRAY_SIZE(apds9960_precious_ranges),
0179 };
0180 
0181 static const struct regmap_range apds9960_readable_ranges[] = {
0182     regmap_reg_range(APDS9960_REG_ENABLE,
0183                 APDS9960_REG_GSTATUS),
0184     regmap_reg_range(APDS9960_REG_GFIFO_DIR(UP),
0185                 APDS9960_REG_GFIFO_DIR(RIGHT)),
0186 };
0187 
0188 static const struct regmap_access_table apds9960_readable_table = {
0189     .yes_ranges = apds9960_readable_ranges,
0190     .n_yes_ranges   = ARRAY_SIZE(apds9960_readable_ranges),
0191 };
0192 
0193 static const struct regmap_range apds9960_writeable_ranges[] = {
0194     regmap_reg_range(APDS9960_REG_ENABLE, APDS9960_REG_CONFIG_2),
0195     regmap_reg_range(APDS9960_REG_POFFSET_UR, APDS9960_REG_GCONF_4),
0196     regmap_reg_range(APDS9960_REG_IFORCE, APDS9960_REG_AICLEAR),
0197 };
0198 
0199 static const struct regmap_access_table apds9960_writeable_table = {
0200     .yes_ranges = apds9960_writeable_ranges,
0201     .n_yes_ranges   = ARRAY_SIZE(apds9960_writeable_ranges),
0202 };
0203 
0204 static const struct regmap_config apds9960_regmap_config = {
0205     .name = APDS9960_REGMAP_NAME,
0206     .reg_bits = 8,
0207     .val_bits = 8,
0208     .use_single_read = true,
0209     .use_single_write = true,
0210 
0211     .volatile_table = &apds9960_volatile_table,
0212     .precious_table = &apds9960_precious_table,
0213     .rd_table = &apds9960_readable_table,
0214     .wr_table = &apds9960_writeable_table,
0215 
0216     .reg_defaults = apds9960_reg_defaults,
0217     .num_reg_defaults = ARRAY_SIZE(apds9960_reg_defaults),
0218     .max_register = APDS9960_REG_GFIFO_DIR(RIGHT),
0219     .cache_type = REGCACHE_RBTREE,
0220 };
0221 
0222 static const struct iio_event_spec apds9960_pxs_event_spec[] = {
0223     {
0224         .type = IIO_EV_TYPE_THRESH,
0225         .dir = IIO_EV_DIR_RISING,
0226         .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0227             BIT(IIO_EV_INFO_ENABLE),
0228     },
0229     {
0230         .type = IIO_EV_TYPE_THRESH,
0231         .dir = IIO_EV_DIR_FALLING,
0232         .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0233             BIT(IIO_EV_INFO_ENABLE),
0234     },
0235 };
0236 
0237 static const struct iio_event_spec apds9960_als_event_spec[] = {
0238     {
0239         .type = IIO_EV_TYPE_THRESH,
0240         .dir = IIO_EV_DIR_RISING,
0241         .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0242             BIT(IIO_EV_INFO_ENABLE),
0243     },
0244     {
0245         .type = IIO_EV_TYPE_THRESH,
0246         .dir = IIO_EV_DIR_FALLING,
0247         .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0248             BIT(IIO_EV_INFO_ENABLE),
0249     },
0250 };
0251 
0252 #define APDS9960_GESTURE_CHANNEL(_dir, _si) { \
0253     .type = IIO_PROXIMITY, \
0254     .channel = _si + 1, \
0255     .scan_index = _si, \
0256     .indexed = 1, \
0257     .scan_type = { \
0258         .sign = 'u', \
0259         .realbits = 8, \
0260         .storagebits = 8, \
0261     }, \
0262 }
0263 
0264 #define APDS9960_INTENSITY_CHANNEL(_colour) { \
0265     .type = IIO_INTENSITY, \
0266     .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0267     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
0268             BIT(IIO_CHAN_INFO_INT_TIME), \
0269     .channel2 = IIO_MOD_LIGHT_##_colour, \
0270     .address = APDS9960_REG_ALS_CHANNEL(_colour), \
0271     .modified = 1, \
0272     .scan_index = -1, \
0273 }
0274 
0275 static const unsigned long apds9960_scan_masks[] = {0xf, 0};
0276 
0277 static const struct iio_chan_spec apds9960_channels[] = {
0278     {
0279         .type = IIO_PROXIMITY,
0280         .address = APDS9960_REG_PDATA,
0281         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0282         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
0283         .channel = 0,
0284         .indexed = 0,
0285         .scan_index = -1,
0286 
0287         .event_spec = apds9960_pxs_event_spec,
0288         .num_event_specs = ARRAY_SIZE(apds9960_pxs_event_spec),
0289     },
0290     /* Gesture Sensor */
0291     APDS9960_GESTURE_CHANNEL(UP, 0),
0292     APDS9960_GESTURE_CHANNEL(DOWN, 1),
0293     APDS9960_GESTURE_CHANNEL(LEFT, 2),
0294     APDS9960_GESTURE_CHANNEL(RIGHT, 3),
0295     /* ALS */
0296     {
0297         .type = IIO_INTENSITY,
0298         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0299         .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
0300             BIT(IIO_CHAN_INFO_INT_TIME),
0301         .channel2 = IIO_MOD_LIGHT_CLEAR,
0302         .address = APDS9960_REG_ALS_CHANNEL(CLEAR),
0303         .modified = 1,
0304         .scan_index = -1,
0305 
0306         .event_spec = apds9960_als_event_spec,
0307         .num_event_specs = ARRAY_SIZE(apds9960_als_event_spec),
0308     },
0309     /* RGB Sensor */
0310     APDS9960_INTENSITY_CHANNEL(RED),
0311     APDS9960_INTENSITY_CHANNEL(GREEN),
0312     APDS9960_INTENSITY_CHANNEL(BLUE),
0313 };
0314 
0315 /* integration time in us */
0316 static const int apds9960_int_time[][2] = {
0317     { 28000, 246},
0318     {100000, 219},
0319     {200000, 182},
0320     {700000,   0}
0321 };
0322 
0323 /* gain mapping */
0324 static const int apds9960_pxs_gain_map[] = {1, 2, 4, 8};
0325 static const int apds9960_als_gain_map[] = {1, 4, 16, 64};
0326 
0327 static IIO_CONST_ATTR(proximity_scale_available, "1 2 4 8");
0328 static IIO_CONST_ATTR(intensity_scale_available, "1 4 16 64");
0329 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.028 0.1 0.2 0.7");
0330 
0331 static struct attribute *apds9960_attributes[] = {
0332     &iio_const_attr_proximity_scale_available.dev_attr.attr,
0333     &iio_const_attr_intensity_scale_available.dev_attr.attr,
0334     &iio_const_attr_integration_time_available.dev_attr.attr,
0335     NULL,
0336 };
0337 
0338 static const struct attribute_group apds9960_attribute_group = {
0339     .attrs = apds9960_attributes,
0340 };
0341 
0342 static const struct reg_field apds9960_reg_field_int_als =
0343                 REG_FIELD(APDS9960_REG_ENABLE, 4, 4);
0344 
0345 static const struct reg_field apds9960_reg_field_int_ges =
0346                 REG_FIELD(APDS9960_REG_GCONF_4, 1, 1);
0347 
0348 static const struct reg_field apds9960_reg_field_int_pxs =
0349                 REG_FIELD(APDS9960_REG_ENABLE, 5, 5);
0350 
0351 static const struct reg_field apds9960_reg_field_enable_als =
0352                 REG_FIELD(APDS9960_REG_ENABLE, 1, 1);
0353 
0354 static const struct reg_field apds9960_reg_field_enable_ges =
0355                 REG_FIELD(APDS9960_REG_ENABLE, 6, 6);
0356 
0357 static const struct reg_field apds9960_reg_field_enable_pxs =
0358                 REG_FIELD(APDS9960_REG_ENABLE, 2, 2);
0359 
0360 static int apds9960_set_it_time(struct apds9960_data *data, int val2)
0361 {
0362     int ret = -EINVAL;
0363     int idx;
0364 
0365     for (idx = 0; idx < ARRAY_SIZE(apds9960_int_time); idx++) {
0366         if (apds9960_int_time[idx][0] == val2) {
0367             mutex_lock(&data->lock);
0368             ret = regmap_write(data->regmap, APDS9960_REG_ATIME,
0369                          apds9960_int_time[idx][1]);
0370             if (!ret)
0371                 data->als_adc_int_us = val2;
0372             mutex_unlock(&data->lock);
0373             break;
0374         }
0375     }
0376 
0377     return ret;
0378 }
0379 
0380 static int apds9960_set_pxs_gain(struct apds9960_data *data, int val)
0381 {
0382     int ret = -EINVAL;
0383     int idx;
0384 
0385     for (idx = 0; idx < ARRAY_SIZE(apds9960_pxs_gain_map); idx++) {
0386         if (apds9960_pxs_gain_map[idx] == val) {
0387             /* pxs + gesture gains are mirrored */
0388             mutex_lock(&data->lock);
0389             ret = regmap_update_bits(data->regmap,
0390                 APDS9960_REG_CONTROL,
0391                 APDS9960_REG_CONTROL_PGAIN_MASK,
0392                 idx << APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT);
0393             if (ret) {
0394                 mutex_unlock(&data->lock);
0395                 break;
0396             }
0397 
0398             ret = regmap_update_bits(data->regmap,
0399                 APDS9960_REG_CONFIG_2,
0400                 APDS9960_REG_CONFIG_2_GGAIN_MASK,
0401                 idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT);
0402             if (!ret)
0403                 data->pxs_gain = idx;
0404             mutex_unlock(&data->lock);
0405             break;
0406         }
0407     }
0408 
0409     return ret;
0410 }
0411 
0412 static int apds9960_set_als_gain(struct apds9960_data *data, int val)
0413 {
0414     int ret = -EINVAL;
0415     int idx;
0416 
0417     for (idx = 0; idx < ARRAY_SIZE(apds9960_als_gain_map); idx++) {
0418         if (apds9960_als_gain_map[idx] == val) {
0419             mutex_lock(&data->lock);
0420             ret = regmap_update_bits(data->regmap,
0421                     APDS9960_REG_CONTROL,
0422                     APDS9960_REG_CONTROL_AGAIN_MASK, idx);
0423             if (!ret)
0424                 data->als_gain = idx;
0425             mutex_unlock(&data->lock);
0426             break;
0427         }
0428     }
0429 
0430     return ret;
0431 }
0432 
0433 #ifdef CONFIG_PM
0434 static int apds9960_set_power_state(struct apds9960_data *data, bool on)
0435 {
0436     struct device *dev = &data->client->dev;
0437     int ret = 0;
0438 
0439     mutex_lock(&data->lock);
0440 
0441     if (on) {
0442         int suspended;
0443 
0444         suspended = pm_runtime_suspended(dev);
0445         ret = pm_runtime_get_sync(dev);
0446 
0447         /* Allow one integration cycle before allowing a reading */
0448         if (suspended)
0449             usleep_range(data->als_adc_int_us,
0450                      APDS9960_MAX_INT_TIME_IN_US);
0451     } else {
0452         pm_runtime_mark_last_busy(dev);
0453         ret = pm_runtime_put_autosuspend(dev);
0454     }
0455 
0456     mutex_unlock(&data->lock);
0457 
0458     return ret;
0459 }
0460 #else
0461 static int apds9960_set_power_state(struct apds9960_data *data, bool on)
0462 {
0463     return 0;
0464 }
0465 #endif
0466 
0467 static int apds9960_read_raw(struct iio_dev *indio_dev,
0468                  struct iio_chan_spec const *chan,
0469                  int *val, int *val2, long mask)
0470 {
0471     struct apds9960_data *data = iio_priv(indio_dev);
0472     __le16 buf;
0473     int ret = -EINVAL;
0474 
0475     if (data->gesture_mode_running)
0476         return -EBUSY;
0477 
0478     switch (mask) {
0479     case IIO_CHAN_INFO_RAW:
0480         apds9960_set_power_state(data, true);
0481         switch (chan->type) {
0482         case IIO_PROXIMITY:
0483             ret = regmap_read(data->regmap, chan->address, val);
0484             if (!ret)
0485                 ret = IIO_VAL_INT;
0486             break;
0487         case IIO_INTENSITY:
0488             ret = regmap_bulk_read(data->regmap, chan->address,
0489                            &buf, 2);
0490             if (!ret) {
0491                 ret = IIO_VAL_INT;
0492                 *val = le16_to_cpu(buf);
0493             }
0494             break;
0495         default:
0496             ret = -EINVAL;
0497         }
0498         apds9960_set_power_state(data, false);
0499         break;
0500     case IIO_CHAN_INFO_INT_TIME:
0501         /* RGB + ALS sensors only have integration time */
0502         mutex_lock(&data->lock);
0503         switch (chan->type) {
0504         case IIO_INTENSITY:
0505             *val = 0;
0506             *val2 = data->als_adc_int_us;
0507             ret = IIO_VAL_INT_PLUS_MICRO;
0508             break;
0509         default:
0510             ret = -EINVAL;
0511         }
0512         mutex_unlock(&data->lock);
0513         break;
0514     case IIO_CHAN_INFO_SCALE:
0515         mutex_lock(&data->lock);
0516         switch (chan->type) {
0517         case IIO_PROXIMITY:
0518             *val = apds9960_pxs_gain_map[data->pxs_gain];
0519             ret = IIO_VAL_INT;
0520             break;
0521         case IIO_INTENSITY:
0522             *val = apds9960_als_gain_map[data->als_gain];
0523             ret = IIO_VAL_INT;
0524             break;
0525         default:
0526             ret = -EINVAL;
0527         }
0528         mutex_unlock(&data->lock);
0529         break;
0530     }
0531 
0532     return ret;
0533 };
0534 
0535 static int apds9960_write_raw(struct iio_dev *indio_dev,
0536                  struct iio_chan_spec const *chan,
0537                  int val, int val2, long mask)
0538 {
0539     struct apds9960_data *data = iio_priv(indio_dev);
0540 
0541     switch (mask) {
0542     case IIO_CHAN_INFO_INT_TIME:
0543         /* RGB + ALS sensors only have int time */
0544         switch (chan->type) {
0545         case IIO_INTENSITY:
0546             if (val != 0)
0547                 return -EINVAL;
0548             return apds9960_set_it_time(data, val2);
0549         default:
0550             return -EINVAL;
0551         }
0552     case IIO_CHAN_INFO_SCALE:
0553         if (val2 != 0)
0554             return -EINVAL;
0555         switch (chan->type) {
0556         case IIO_PROXIMITY:
0557             return apds9960_set_pxs_gain(data, val);
0558         case IIO_INTENSITY:
0559             return apds9960_set_als_gain(data, val);
0560         default:
0561             return -EINVAL;
0562         }
0563     default:
0564         return -EINVAL;
0565     }
0566 
0567     return 0;
0568 }
0569 
0570 static inline int apds9960_get_thres_reg(const struct iio_chan_spec *chan,
0571                      enum iio_event_direction dir,
0572                      u8 *reg)
0573 {
0574     switch (dir) {
0575     case IIO_EV_DIR_RISING:
0576         switch (chan->type) {
0577         case IIO_PROXIMITY:
0578             *reg = APDS9960_REG_PIHT;
0579             break;
0580         case IIO_INTENSITY:
0581             *reg = APDS9960_REG_AIHTL;
0582             break;
0583         default:
0584             return -EINVAL;
0585         }
0586         break;
0587     case IIO_EV_DIR_FALLING:
0588         switch (chan->type) {
0589         case IIO_PROXIMITY:
0590             *reg = APDS9960_REG_PILT;
0591             break;
0592         case IIO_INTENSITY:
0593             *reg = APDS9960_REG_AILTL;
0594             break;
0595         default:
0596             return -EINVAL;
0597         }
0598         break;
0599     default:
0600         return -EINVAL;
0601     }
0602 
0603     return 0;
0604 }
0605 
0606 static int apds9960_read_event(struct iio_dev *indio_dev,
0607                    const struct iio_chan_spec *chan,
0608                    enum iio_event_type type,
0609                    enum iio_event_direction dir,
0610                    enum iio_event_info info,
0611                    int *val, int *val2)
0612 {
0613     u8 reg;
0614     __le16 buf;
0615     int ret = 0;
0616     struct apds9960_data *data = iio_priv(indio_dev);
0617 
0618     if (info != IIO_EV_INFO_VALUE)
0619         return -EINVAL;
0620 
0621     ret = apds9960_get_thres_reg(chan, dir, &reg);
0622     if (ret < 0)
0623         return ret;
0624 
0625     if (chan->type == IIO_PROXIMITY) {
0626         ret = regmap_read(data->regmap, reg, val);
0627         if (ret < 0)
0628             return ret;
0629     } else if (chan->type == IIO_INTENSITY) {
0630         ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
0631         if (ret < 0)
0632             return ret;
0633         *val = le16_to_cpu(buf);
0634     } else
0635         return -EINVAL;
0636 
0637     *val2 = 0;
0638 
0639     return IIO_VAL_INT;
0640 }
0641 
0642 static int apds9960_write_event(struct iio_dev *indio_dev,
0643                 const struct iio_chan_spec *chan,
0644                 enum iio_event_type type,
0645                 enum iio_event_direction dir,
0646                 enum iio_event_info info,
0647                 int val, int val2)
0648 {
0649     u8 reg;
0650     __le16 buf;
0651     int ret = 0;
0652     struct apds9960_data *data = iio_priv(indio_dev);
0653 
0654     if (info != IIO_EV_INFO_VALUE)
0655         return -EINVAL;
0656 
0657     ret = apds9960_get_thres_reg(chan, dir, &reg);
0658     if (ret < 0)
0659         return ret;
0660 
0661     if (chan->type == IIO_PROXIMITY) {
0662         if (val < 0 || val > APDS9960_MAX_PXS_THRES_VAL)
0663             return -EINVAL;
0664         ret = regmap_write(data->regmap, reg, val);
0665         if (ret < 0)
0666             return ret;
0667     } else if (chan->type == IIO_INTENSITY) {
0668         if (val < 0 || val > APDS9960_MAX_ALS_THRES_VAL)
0669             return -EINVAL;
0670         buf = cpu_to_le16(val);
0671         ret = regmap_bulk_write(data->regmap, reg, &buf, 2);
0672         if (ret < 0)
0673             return ret;
0674     } else
0675         return -EINVAL;
0676 
0677     return 0;
0678 }
0679 
0680 static int apds9960_read_event_config(struct iio_dev *indio_dev,
0681                       const struct iio_chan_spec *chan,
0682                       enum iio_event_type type,
0683                       enum iio_event_direction dir)
0684 {
0685     struct apds9960_data *data = iio_priv(indio_dev);
0686 
0687     switch (chan->type) {
0688     case IIO_PROXIMITY:
0689         return data->pxs_int;
0690     case IIO_INTENSITY:
0691         return data->als_int;
0692     default:
0693         return -EINVAL;
0694     }
0695 
0696     return 0;
0697 }
0698 
0699 static int apds9960_write_event_config(struct iio_dev *indio_dev,
0700                        const struct iio_chan_spec *chan,
0701                        enum iio_event_type type,
0702                        enum iio_event_direction dir,
0703                        int state)
0704 {
0705     struct apds9960_data *data = iio_priv(indio_dev);
0706     int ret;
0707 
0708     state = !!state;
0709 
0710     switch (chan->type) {
0711     case IIO_PROXIMITY:
0712         if (data->pxs_int == state)
0713             return -EINVAL;
0714 
0715         ret = regmap_field_write(data->reg_int_pxs, state);
0716         if (ret)
0717             return ret;
0718         data->pxs_int = state;
0719         apds9960_set_power_state(data, state);
0720         break;
0721     case IIO_INTENSITY:
0722         if (data->als_int == state)
0723             return -EINVAL;
0724 
0725         ret = regmap_field_write(data->reg_int_als, state);
0726         if (ret)
0727             return ret;
0728         data->als_int = state;
0729         apds9960_set_power_state(data, state);
0730         break;
0731     default:
0732         return -EINVAL;
0733     }
0734 
0735     return 0;
0736 }
0737 
0738 static const struct iio_info apds9960_info = {
0739     .attrs = &apds9960_attribute_group,
0740     .read_raw = apds9960_read_raw,
0741     .write_raw = apds9960_write_raw,
0742     .read_event_value = apds9960_read_event,
0743     .write_event_value = apds9960_write_event,
0744     .read_event_config = apds9960_read_event_config,
0745     .write_event_config = apds9960_write_event_config,
0746 
0747 };
0748 
0749 static inline int apds9660_fifo_is_empty(struct apds9960_data *data)
0750 {
0751     int cnt;
0752     int ret;
0753 
0754     ret = regmap_read(data->regmap, APDS9960_REG_GFLVL, &cnt);
0755     if (ret)
0756         return ret;
0757 
0758     return cnt;
0759 }
0760 
0761 static void apds9960_read_gesture_fifo(struct apds9960_data *data)
0762 {
0763     int ret, cnt = 0;
0764 
0765     mutex_lock(&data->lock);
0766     data->gesture_mode_running = 1;
0767 
0768     while (cnt || (cnt = apds9660_fifo_is_empty(data) > 0)) {
0769         ret = regmap_bulk_read(data->regmap, APDS9960_REG_GFIFO_BASE,
0770                       &data->buffer, 4);
0771 
0772         if (ret)
0773             goto err_read;
0774 
0775         iio_push_to_buffers(data->indio_dev, data->buffer);
0776         cnt--;
0777     }
0778 
0779 err_read:
0780     data->gesture_mode_running = 0;
0781     mutex_unlock(&data->lock);
0782 }
0783 
0784 static irqreturn_t apds9960_interrupt_handler(int irq, void *private)
0785 {
0786     struct iio_dev *indio_dev = private;
0787     struct apds9960_data *data = iio_priv(indio_dev);
0788     int ret, status;
0789 
0790     ret = regmap_read(data->regmap, APDS9960_REG_STATUS, &status);
0791     if (ret < 0) {
0792         dev_err(&data->client->dev, "irq status reg read failed\n");
0793         return IRQ_HANDLED;
0794     }
0795 
0796     if ((status & APDS9960_REG_STATUS_ALS_INT) && data->als_int) {
0797         iio_push_event(indio_dev,
0798                    IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
0799                             IIO_EV_TYPE_THRESH,
0800                             IIO_EV_DIR_EITHER),
0801                    iio_get_time_ns(indio_dev));
0802         regmap_write(data->regmap, APDS9960_REG_CICLEAR, 1);
0803     }
0804 
0805     if ((status & APDS9960_REG_STATUS_PS_INT) && data->pxs_int) {
0806         iio_push_event(indio_dev,
0807                    IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
0808                             IIO_EV_TYPE_THRESH,
0809                             IIO_EV_DIR_EITHER),
0810                    iio_get_time_ns(indio_dev));
0811         regmap_write(data->regmap, APDS9960_REG_PICLEAR, 1);
0812     }
0813 
0814     if (status & APDS9960_REG_STATUS_GINT)
0815         apds9960_read_gesture_fifo(data);
0816 
0817     return IRQ_HANDLED;
0818 }
0819 
0820 static int apds9960_set_powermode(struct apds9960_data *data, bool state)
0821 {
0822     return regmap_update_bits(data->regmap, APDS9960_REG_ENABLE, 1, state);
0823 }
0824 
0825 static int apds9960_buffer_postenable(struct iio_dev *indio_dev)
0826 {
0827     struct apds9960_data *data = iio_priv(indio_dev);
0828     int ret;
0829 
0830     ret = regmap_field_write(data->reg_int_ges, 1);
0831     if (ret)
0832         return ret;
0833 
0834     ret = regmap_field_write(data->reg_enable_ges, 1);
0835     if (ret)
0836         return ret;
0837 
0838     pm_runtime_get_sync(&data->client->dev);
0839 
0840     return 0;
0841 }
0842 
0843 static int apds9960_buffer_predisable(struct iio_dev *indio_dev)
0844 {
0845     struct apds9960_data *data = iio_priv(indio_dev);
0846     int ret;
0847 
0848     ret = regmap_field_write(data->reg_enable_ges, 0);
0849     if (ret)
0850         return ret;
0851 
0852     ret = regmap_field_write(data->reg_int_ges, 0);
0853     if (ret)
0854         return ret;
0855 
0856     pm_runtime_put_autosuspend(&data->client->dev);
0857 
0858     return 0;
0859 }
0860 
0861 static const struct iio_buffer_setup_ops apds9960_buffer_setup_ops = {
0862     .postenable = apds9960_buffer_postenable,
0863     .predisable = apds9960_buffer_predisable,
0864 };
0865 
0866 static int apds9960_regfield_init(struct apds9960_data *data)
0867 {
0868     struct device *dev = &data->client->dev;
0869     struct regmap *regmap = data->regmap;
0870 
0871     data->reg_int_als = devm_regmap_field_alloc(dev, regmap,
0872                         apds9960_reg_field_int_als);
0873     if (IS_ERR(data->reg_int_als)) {
0874         dev_err(dev, "INT ALS reg field init failed\n");
0875         return PTR_ERR(data->reg_int_als);
0876     }
0877 
0878     data->reg_int_ges = devm_regmap_field_alloc(dev, regmap,
0879                         apds9960_reg_field_int_ges);
0880     if (IS_ERR(data->reg_int_ges)) {
0881         dev_err(dev, "INT gesture reg field init failed\n");
0882         return PTR_ERR(data->reg_int_ges);
0883     }
0884 
0885     data->reg_int_pxs = devm_regmap_field_alloc(dev, regmap,
0886                         apds9960_reg_field_int_pxs);
0887     if (IS_ERR(data->reg_int_pxs)) {
0888         dev_err(dev, "INT pxs reg field init failed\n");
0889         return PTR_ERR(data->reg_int_pxs);
0890     }
0891 
0892     data->reg_enable_als = devm_regmap_field_alloc(dev, regmap,
0893                         apds9960_reg_field_enable_als);
0894     if (IS_ERR(data->reg_enable_als)) {
0895         dev_err(dev, "Enable ALS reg field init failed\n");
0896         return PTR_ERR(data->reg_enable_als);
0897     }
0898 
0899     data->reg_enable_ges = devm_regmap_field_alloc(dev, regmap,
0900                         apds9960_reg_field_enable_ges);
0901     if (IS_ERR(data->reg_enable_ges)) {
0902         dev_err(dev, "Enable gesture reg field init failed\n");
0903         return PTR_ERR(data->reg_enable_ges);
0904     }
0905 
0906     data->reg_enable_pxs = devm_regmap_field_alloc(dev, regmap,
0907                         apds9960_reg_field_enable_pxs);
0908     if (IS_ERR(data->reg_enable_pxs)) {
0909         dev_err(dev, "Enable PXS reg field init failed\n");
0910         return PTR_ERR(data->reg_enable_pxs);
0911     }
0912 
0913     return 0;
0914 }
0915 
0916 static int apds9960_chip_init(struct apds9960_data *data)
0917 {
0918     int ret;
0919 
0920     /* Default IT for ALS of 28 ms */
0921     ret = apds9960_set_it_time(data, 28000);
0922     if (ret)
0923         return ret;
0924 
0925     /* Ensure gesture interrupt is OFF */
0926     ret = regmap_field_write(data->reg_int_ges, 0);
0927     if (ret)
0928         return ret;
0929 
0930     /* Disable gesture sensor, since polling is useless from user-space */
0931     ret = regmap_field_write(data->reg_enable_ges, 0);
0932     if (ret)
0933         return ret;
0934 
0935     /* Ensure proximity interrupt is OFF */
0936     ret = regmap_field_write(data->reg_int_pxs, 0);
0937     if (ret)
0938         return ret;
0939 
0940     /* Enable proximity sensor for polling */
0941     ret = regmap_field_write(data->reg_enable_pxs, 1);
0942     if (ret)
0943         return ret;
0944 
0945     /* Ensure ALS interrupt is OFF */
0946     ret = regmap_field_write(data->reg_int_als, 0);
0947     if (ret)
0948         return ret;
0949 
0950     /* Enable ALS sensor for polling */
0951     ret = regmap_field_write(data->reg_enable_als, 1);
0952     if (ret)
0953         return ret;
0954     /*
0955      * When enabled trigger an interrupt after 3 readings
0956      * outside threshold for ALS + PXS
0957      */
0958     ret = regmap_write(data->regmap, APDS9960_REG_PERS,
0959                APDS9960_DEFAULT_PERS);
0960     if (ret)
0961         return ret;
0962 
0963     /*
0964      * Wait for 4 event outside gesture threshold to prevent interrupt
0965      * flooding.
0966      */
0967     ret = regmap_update_bits(data->regmap, APDS9960_REG_GCONF_1,
0968             APDS9960_REG_GCONF_1_GFIFO_THRES_MASK,
0969             BIT(0) << APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT);
0970     if (ret)
0971         return ret;
0972 
0973     /* Default ENTER and EXIT thresholds for the GESTURE engine. */
0974     ret = regmap_write(data->regmap, APDS9960_REG_GPENTH,
0975                APDS9960_DEFAULT_GPENTH);
0976     if (ret)
0977         return ret;
0978 
0979     ret = regmap_write(data->regmap, APDS9960_REG_GEXTH,
0980                APDS9960_DEFAULT_GEXTH);
0981     if (ret)
0982         return ret;
0983 
0984     return apds9960_set_powermode(data, 1);
0985 }
0986 
0987 static int apds9960_probe(struct i2c_client *client,
0988               const struct i2c_device_id *id)
0989 {
0990     struct apds9960_data *data;
0991     struct iio_dev *indio_dev;
0992     int ret;
0993 
0994     indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0995     if (!indio_dev)
0996         return -ENOMEM;
0997 
0998     indio_dev->info = &apds9960_info;
0999     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 
1064 error_power_down:
1065     apds9960_set_power_state(data, false);
1066 
1067     return ret;
1068 }
1069 
1070 static 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
1084 static 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 
1092 static 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 
1101 static 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 
1108 static const struct i2c_device_id apds9960_id[] = {
1109     { "apds9960", 0 },
1110     {}
1111 };
1112 MODULE_DEVICE_TABLE(i2c, apds9960_id);
1113 
1114 static const struct acpi_device_id apds9960_acpi_match[] = {
1115     { "MSHW0184" },
1116     { }
1117 };
1118 MODULE_DEVICE_TABLE(acpi, apds9960_acpi_match);
1119 
1120 static const struct of_device_id apds9960_of_match[] = {
1121     { .compatible = "avago,apds9960" },
1122     { }
1123 };
1124 MODULE_DEVICE_TABLE(of, apds9960_of_match);
1125 
1126 static 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 };
1137 module_i2c_driver(apds9960_driver);
1138 
1139 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
1140 MODULE_DESCRIPTION("APDS9960 Gesture/RGB/ALS/Proximity sensor");
1141 MODULE_LICENSE("GPL");