0001
0002
0003
0004
0005
0006
0007
0008
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
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
0136 int als_int;
0137 int pxs_int;
0138 int gesture_mode_running;
0139
0140
0141 int als_gain;
0142 int pxs_gain;
0143
0144
0145 int als_adc_int_us;
0146
0147
0148 u8 buffer[4];
0149 };
0150
0151 static const struct reg_default apds9960_reg_defaults[] = {
0152
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
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
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
0310 APDS9960_INTENSITY_CHANNEL(RED),
0311 APDS9960_INTENSITY_CHANNEL(GREEN),
0312 APDS9960_INTENSITY_CHANNEL(BLUE),
0313 };
0314
0315
0316 static const int apds9960_int_time[][2] = {
0317 { 28000, 246},
0318 {100000, 219},
0319 {200000, 182},
0320 {700000, 0}
0321 };
0322
0323
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
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
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
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
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, ®);
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, ®);
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
0921 ret = apds9960_set_it_time(data, 28000);
0922 if (ret)
0923 return ret;
0924
0925
0926 ret = regmap_field_write(data->reg_int_ges, 0);
0927 if (ret)
0928 return ret;
0929
0930
0931 ret = regmap_field_write(data->reg_enable_ges, 0);
0932 if (ret)
0933 return ret;
0934
0935
0936 ret = regmap_field_write(data->reg_int_pxs, 0);
0937 if (ret)
0938 return ret;
0939
0940
0941 ret = regmap_field_write(data->reg_enable_pxs, 1);
0942 if (ret)
0943 return ret;
0944
0945
0946 ret = regmap_field_write(data->reg_int_als, 0);
0947 if (ret)
0948 return ret;
0949
0950
0951 ret = regmap_field_write(data->reg_enable_als, 1);
0952 if (ret)
0953 return ret;
0954
0955
0956
0957
0958 ret = regmap_write(data->regmap, APDS9960_REG_PERS,
0959 APDS9960_DEFAULT_PERS);
0960 if (ret)
0961 return ret;
0962
0963
0964
0965
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
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");