0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/acpi.h>
0013 #include <linux/delay.h>
0014 #include <linux/i2c.h>
0015 #include <linux/iio/events.h>
0016 #include <linux/iio/iio.h>
0017 #include <linux/interrupt.h>
0018 #include <linux/irq.h>
0019 #include <linux/iio/sysfs.h>
0020 #include <linux/mutex.h>
0021 #include <linux/pm.h>
0022 #include <linux/pm_runtime.h>
0023
0024 #define US5182D_REG_CFG0 0x00
0025 #define US5182D_CFG0_ONESHOT_EN BIT(6)
0026 #define US5182D_CFG0_SHUTDOWN_EN BIT(7)
0027 #define US5182D_CFG0_WORD_ENABLE BIT(0)
0028 #define US5182D_CFG0_PROX BIT(3)
0029 #define US5182D_CFG0_PX_IRQ BIT(2)
0030
0031 #define US5182D_REG_CFG1 0x01
0032 #define US5182D_CFG1_ALS_RES16 BIT(4)
0033 #define US5182D_CFG1_AGAIN_DEFAULT 0x00
0034
0035 #define US5182D_REG_CFG2 0x02
0036 #define US5182D_CFG2_PX_RES16 BIT(4)
0037 #define US5182D_CFG2_PXGAIN_DEFAULT BIT(2)
0038
0039 #define US5182D_REG_CFG3 0x03
0040 #define US5182D_CFG3_LED_CURRENT100 (BIT(4) | BIT(5))
0041 #define US5182D_CFG3_INT_SOURCE_PX BIT(3)
0042
0043 #define US5182D_REG_CFG4 0x10
0044
0045
0046
0047
0048
0049
0050
0051 #define US5182D_REG_UDARK_TH 0x27
0052 #define US5182D_REG_DARK_AUTO_EN 0x2b
0053 #define US5182D_REG_AUTO_LDARK_GAIN 0x29
0054 #define US5182D_REG_AUTO_HDARK_GAIN 0x2a
0055
0056
0057 #define US5182D_REG_PXL_TH 0x08
0058 #define US5182D_REG_PXH_TH 0x0a
0059
0060 #define US5182D_REG_PXL_TH_DEFAULT 1000
0061 #define US5182D_REG_PXH_TH_DEFAULT 30000
0062
0063 #define US5182D_OPMODE_ALS 0x01
0064 #define US5182D_OPMODE_PX 0x02
0065 #define US5182D_OPMODE_SHIFT 4
0066
0067 #define US5182D_REG_DARK_AUTO_EN_DEFAULT 0x80
0068 #define US5182D_REG_AUTO_LDARK_GAIN_DEFAULT 0x16
0069 #define US5182D_REG_AUTO_HDARK_GAIN_DEFAULT 0x00
0070
0071 #define US5182D_REG_ADL 0x0c
0072 #define US5182D_REG_PDL 0x0e
0073
0074 #define US5182D_REG_MODE_STORE 0x21
0075 #define US5182D_STORE_MODE 0x01
0076
0077 #define US5182D_REG_CHIPID 0xb2
0078
0079 #define US5182D_OPMODE_MASK GENMASK(5, 4)
0080 #define US5182D_AGAIN_MASK 0x07
0081 #define US5182D_RESET_CHIP 0x01
0082
0083 #define US5182D_CHIPID 0x26
0084 #define US5182D_DRV_NAME "us5182d"
0085
0086 #define US5182D_GA_RESOLUTION 1000
0087
0088 #define US5182D_READ_BYTE 1
0089 #define US5182D_READ_WORD 2
0090 #define US5182D_OPSTORE_SLEEP_TIME 20
0091 #define US5182D_SLEEP_MS 3000
0092 #define US5182D_PXH_TH_DISABLE 0xffff
0093 #define US5182D_PXL_TH_DISABLE 0x0000
0094
0095
0096 static const int us5182d_scales[] = {188500, 107800, 61000, 33600, 19600, 7600,
0097 3900, 2100};
0098
0099
0100
0101
0102
0103 static u16 us5182d_dark_ths_vals[] = {170, 200, 512, 512, 800, 2000, 4000,
0104 8000};
0105
0106 enum mode {
0107 US5182D_ALS_PX,
0108 US5182D_ALS_ONLY,
0109 US5182D_PX_ONLY
0110 };
0111
0112 enum pmode {
0113 US5182D_CONTINUOUS,
0114 US5182D_ONESHOT
0115 };
0116
0117 struct us5182d_data {
0118 struct i2c_client *client;
0119 struct mutex lock;
0120
0121
0122 u32 ga;
0123
0124
0125 u8 lower_dark_gain;
0126 u8 upper_dark_gain;
0127 u16 *us5182d_dark_ths;
0128
0129 u16 px_low_th;
0130 u16 px_high_th;
0131
0132 int rising_en;
0133 int falling_en;
0134
0135 u8 opmode;
0136 u8 power_mode;
0137
0138 bool als_enabled;
0139 bool px_enabled;
0140
0141 bool default_continuous;
0142 };
0143
0144 static IIO_CONST_ATTR(in_illuminance_scale_available,
0145 "0.0021 0.0039 0.0076 0.0196 0.0336 0.061 0.1078 0.1885");
0146
0147 static struct attribute *us5182d_attrs[] = {
0148 &iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
0149 NULL
0150 };
0151
0152 static const struct attribute_group us5182d_attr_group = {
0153 .attrs = us5182d_attrs,
0154 };
0155
0156 static const struct {
0157 u8 reg;
0158 u8 val;
0159 } us5182d_regvals[] = {
0160 {US5182D_REG_CFG0, US5182D_CFG0_WORD_ENABLE},
0161 {US5182D_REG_CFG1, US5182D_CFG1_ALS_RES16},
0162 {US5182D_REG_CFG2, (US5182D_CFG2_PX_RES16 |
0163 US5182D_CFG2_PXGAIN_DEFAULT)},
0164 {US5182D_REG_CFG3, US5182D_CFG3_LED_CURRENT100 |
0165 US5182D_CFG3_INT_SOURCE_PX},
0166 {US5182D_REG_CFG4, 0x00},
0167 };
0168
0169 static const struct iio_event_spec us5182d_events[] = {
0170 {
0171 .type = IIO_EV_TYPE_THRESH,
0172 .dir = IIO_EV_DIR_RISING,
0173 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0174 BIT(IIO_EV_INFO_ENABLE),
0175 },
0176 {
0177 .type = IIO_EV_TYPE_THRESH,
0178 .dir = IIO_EV_DIR_FALLING,
0179 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0180 BIT(IIO_EV_INFO_ENABLE),
0181 },
0182 };
0183
0184 static const struct iio_chan_spec us5182d_channels[] = {
0185 {
0186 .type = IIO_LIGHT,
0187 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0188 BIT(IIO_CHAN_INFO_SCALE),
0189 },
0190 {
0191 .type = IIO_PROXIMITY,
0192 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0193 .event_spec = us5182d_events,
0194 .num_event_specs = ARRAY_SIZE(us5182d_events),
0195 }
0196 };
0197
0198 static int us5182d_oneshot_en(struct us5182d_data *data)
0199 {
0200 int ret;
0201
0202 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
0203 if (ret < 0)
0204 return ret;
0205
0206
0207
0208
0209
0210 ret = ret | US5182D_CFG0_ONESHOT_EN;
0211
0212 return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
0213 }
0214
0215 static int us5182d_set_opmode(struct us5182d_data *data, u8 mode)
0216 {
0217 int ret;
0218
0219 if (mode == data->opmode)
0220 return 0;
0221
0222 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
0223 if (ret < 0)
0224 return ret;
0225
0226
0227 ret = ret & ~US5182D_OPMODE_MASK;
0228 ret = ret | (mode << US5182D_OPMODE_SHIFT);
0229
0230
0231
0232
0233
0234
0235 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
0236 if (ret < 0)
0237 return ret;
0238
0239 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_MODE_STORE,
0240 US5182D_STORE_MODE);
0241 if (ret < 0)
0242 return ret;
0243
0244 data->opmode = mode;
0245 msleep(US5182D_OPSTORE_SLEEP_TIME);
0246
0247 return 0;
0248 }
0249
0250 static int us5182d_als_enable(struct us5182d_data *data)
0251 {
0252 int ret;
0253 u8 mode;
0254
0255 if (data->power_mode == US5182D_ONESHOT) {
0256 ret = us5182d_set_opmode(data, US5182D_ALS_ONLY);
0257 if (ret < 0)
0258 return ret;
0259 data->px_enabled = false;
0260 }
0261
0262 if (data->als_enabled)
0263 return 0;
0264
0265 mode = data->px_enabled ? US5182D_ALS_PX : US5182D_ALS_ONLY;
0266
0267 ret = us5182d_set_opmode(data, mode);
0268 if (ret < 0)
0269 return ret;
0270
0271 data->als_enabled = true;
0272
0273 return 0;
0274 }
0275
0276 static int us5182d_px_enable(struct us5182d_data *data)
0277 {
0278 int ret;
0279 u8 mode;
0280
0281 if (data->power_mode == US5182D_ONESHOT) {
0282 ret = us5182d_set_opmode(data, US5182D_PX_ONLY);
0283 if (ret < 0)
0284 return ret;
0285 data->als_enabled = false;
0286 }
0287
0288 if (data->px_enabled)
0289 return 0;
0290
0291 mode = data->als_enabled ? US5182D_ALS_PX : US5182D_PX_ONLY;
0292
0293 ret = us5182d_set_opmode(data, mode);
0294 if (ret < 0)
0295 return ret;
0296
0297 data->px_enabled = true;
0298
0299 return 0;
0300 }
0301
0302 static int us5182d_get_als(struct us5182d_data *data)
0303 {
0304 int ret;
0305 unsigned long result;
0306
0307 ret = us5182d_als_enable(data);
0308 if (ret < 0)
0309 return ret;
0310
0311 ret = i2c_smbus_read_word_data(data->client,
0312 US5182D_REG_ADL);
0313 if (ret < 0)
0314 return ret;
0315
0316 result = ret * data->ga / US5182D_GA_RESOLUTION;
0317 if (result > 0xffff)
0318 result = 0xffff;
0319
0320 return result;
0321 }
0322
0323 static int us5182d_get_px(struct us5182d_data *data)
0324 {
0325 int ret;
0326
0327 ret = us5182d_px_enable(data);
0328 if (ret < 0)
0329 return ret;
0330
0331 return i2c_smbus_read_word_data(data->client,
0332 US5182D_REG_PDL);
0333 }
0334
0335 static int us5182d_shutdown_en(struct us5182d_data *data, u8 state)
0336 {
0337 int ret;
0338
0339 if (data->power_mode == US5182D_ONESHOT)
0340 return 0;
0341
0342 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
0343 if (ret < 0)
0344 return ret;
0345
0346 ret = ret & ~US5182D_CFG0_SHUTDOWN_EN;
0347 ret = ret | state;
0348
0349 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0, ret);
0350 if (ret < 0)
0351 return ret;
0352
0353 if (state & US5182D_CFG0_SHUTDOWN_EN) {
0354 data->als_enabled = false;
0355 data->px_enabled = false;
0356 }
0357
0358 return ret;
0359 }
0360
0361
0362 static int us5182d_set_power_state(struct us5182d_data *data, bool on)
0363 {
0364 int ret;
0365
0366 if (data->power_mode == US5182D_ONESHOT)
0367 return 0;
0368
0369 if (on) {
0370 ret = pm_runtime_resume_and_get(&data->client->dev);
0371 } else {
0372 pm_runtime_mark_last_busy(&data->client->dev);
0373 ret = pm_runtime_put_autosuspend(&data->client->dev);
0374 }
0375
0376 return ret;
0377 }
0378
0379 static int us5182d_read_value(struct us5182d_data *data,
0380 struct iio_chan_spec const *chan)
0381 {
0382 int ret, value;
0383
0384 mutex_lock(&data->lock);
0385
0386 if (data->power_mode == US5182D_ONESHOT) {
0387 ret = us5182d_oneshot_en(data);
0388 if (ret < 0)
0389 goto out_err;
0390 }
0391
0392 ret = us5182d_set_power_state(data, true);
0393 if (ret < 0)
0394 goto out_err;
0395
0396 if (chan->type == IIO_LIGHT)
0397 ret = us5182d_get_als(data);
0398 else
0399 ret = us5182d_get_px(data);
0400 if (ret < 0)
0401 goto out_poweroff;
0402
0403 value = ret;
0404
0405 ret = us5182d_set_power_state(data, false);
0406 if (ret < 0)
0407 goto out_err;
0408
0409 mutex_unlock(&data->lock);
0410 return value;
0411
0412 out_poweroff:
0413 us5182d_set_power_state(data, false);
0414 out_err:
0415 mutex_unlock(&data->lock);
0416 return ret;
0417 }
0418
0419 static int us5182d_read_raw(struct iio_dev *indio_dev,
0420 struct iio_chan_spec const *chan, int *val,
0421 int *val2, long mask)
0422 {
0423 struct us5182d_data *data = iio_priv(indio_dev);
0424 int ret;
0425
0426 switch (mask) {
0427 case IIO_CHAN_INFO_RAW:
0428 ret = us5182d_read_value(data, chan);
0429 if (ret < 0)
0430 return ret;
0431 *val = ret;
0432 return IIO_VAL_INT;
0433 case IIO_CHAN_INFO_SCALE:
0434 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
0435 if (ret < 0)
0436 return ret;
0437 *val = 0;
0438 *val2 = us5182d_scales[ret & US5182D_AGAIN_MASK];
0439 return IIO_VAL_INT_PLUS_MICRO;
0440 default:
0441 return -EINVAL;
0442 }
0443 }
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454 static int us5182d_update_dark_th(struct us5182d_data *data, int index)
0455 {
0456 __be16 dark_th = cpu_to_be16(data->us5182d_dark_ths[index]);
0457 int ret;
0458
0459 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH,
0460 ((u8 *)&dark_th)[0]);
0461 if (ret < 0)
0462 return ret;
0463
0464 return i2c_smbus_write_byte_data(data->client, US5182D_REG_UDARK_TH + 1,
0465 ((u8 *)&dark_th)[1]);
0466 }
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476 static int us5182d_apply_scale(struct us5182d_data *data, int index)
0477 {
0478 int ret;
0479
0480 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG1);
0481 if (ret < 0)
0482 return ret;
0483
0484 ret = ret & (~US5182D_AGAIN_MASK);
0485 ret |= index;
0486
0487 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG1, ret);
0488 if (ret < 0)
0489 return ret;
0490
0491 return us5182d_update_dark_th(data, index);
0492 }
0493
0494 static int us5182d_write_raw(struct iio_dev *indio_dev,
0495 struct iio_chan_spec const *chan, int val,
0496 int val2, long mask)
0497 {
0498 struct us5182d_data *data = iio_priv(indio_dev);
0499 int ret, i;
0500
0501 switch (mask) {
0502 case IIO_CHAN_INFO_SCALE:
0503 if (val != 0)
0504 return -EINVAL;
0505 for (i = 0; i < ARRAY_SIZE(us5182d_scales); i++)
0506 if (val2 == us5182d_scales[i]) {
0507 mutex_lock(&data->lock);
0508 ret = us5182d_apply_scale(data, i);
0509 mutex_unlock(&data->lock);
0510 return ret;
0511 }
0512 break;
0513 default:
0514 return -EINVAL;
0515 }
0516
0517 return -EINVAL;
0518 }
0519
0520 static int us5182d_setup_prox(struct iio_dev *indio_dev,
0521 enum iio_event_direction dir, u16 val)
0522 {
0523 struct us5182d_data *data = iio_priv(indio_dev);
0524
0525 if (dir == IIO_EV_DIR_FALLING)
0526 return i2c_smbus_write_word_data(data->client,
0527 US5182D_REG_PXL_TH, val);
0528 else if (dir == IIO_EV_DIR_RISING)
0529 return i2c_smbus_write_word_data(data->client,
0530 US5182D_REG_PXH_TH, val);
0531
0532 return 0;
0533 }
0534
0535 static int us5182d_read_thresh(struct iio_dev *indio_dev,
0536 const struct iio_chan_spec *chan, enum iio_event_type type,
0537 enum iio_event_direction dir, enum iio_event_info info, int *val,
0538 int *val2)
0539 {
0540 struct us5182d_data *data = iio_priv(indio_dev);
0541
0542 switch (dir) {
0543 case IIO_EV_DIR_RISING:
0544 mutex_lock(&data->lock);
0545 *val = data->px_high_th;
0546 mutex_unlock(&data->lock);
0547 break;
0548 case IIO_EV_DIR_FALLING:
0549 mutex_lock(&data->lock);
0550 *val = data->px_low_th;
0551 mutex_unlock(&data->lock);
0552 break;
0553 default:
0554 return -EINVAL;
0555 }
0556
0557 return IIO_VAL_INT;
0558 }
0559
0560 static int us5182d_write_thresh(struct iio_dev *indio_dev,
0561 const struct iio_chan_spec *chan, enum iio_event_type type,
0562 enum iio_event_direction dir, enum iio_event_info info, int val,
0563 int val2)
0564 {
0565 struct us5182d_data *data = iio_priv(indio_dev);
0566 int ret;
0567
0568 if (val < 0 || val > USHRT_MAX || val2 != 0)
0569 return -EINVAL;
0570
0571 switch (dir) {
0572 case IIO_EV_DIR_RISING:
0573 mutex_lock(&data->lock);
0574 if (data->rising_en) {
0575 ret = us5182d_setup_prox(indio_dev, dir, val);
0576 if (ret < 0)
0577 goto err;
0578 }
0579 data->px_high_th = val;
0580 mutex_unlock(&data->lock);
0581 break;
0582 case IIO_EV_DIR_FALLING:
0583 mutex_lock(&data->lock);
0584 if (data->falling_en) {
0585 ret = us5182d_setup_prox(indio_dev, dir, val);
0586 if (ret < 0)
0587 goto err;
0588 }
0589 data->px_low_th = val;
0590 mutex_unlock(&data->lock);
0591 break;
0592 default:
0593 return -EINVAL;
0594 }
0595
0596 return 0;
0597 err:
0598 mutex_unlock(&data->lock);
0599 return ret;
0600 }
0601
0602 static int us5182d_read_event_config(struct iio_dev *indio_dev,
0603 const struct iio_chan_spec *chan, enum iio_event_type type,
0604 enum iio_event_direction dir)
0605 {
0606 struct us5182d_data *data = iio_priv(indio_dev);
0607 int ret;
0608
0609 switch (dir) {
0610 case IIO_EV_DIR_RISING:
0611 mutex_lock(&data->lock);
0612 ret = data->rising_en;
0613 mutex_unlock(&data->lock);
0614 break;
0615 case IIO_EV_DIR_FALLING:
0616 mutex_lock(&data->lock);
0617 ret = data->falling_en;
0618 mutex_unlock(&data->lock);
0619 break;
0620 default:
0621 ret = -EINVAL;
0622 break;
0623 }
0624
0625 return ret;
0626 }
0627
0628 static int us5182d_write_event_config(struct iio_dev *indio_dev,
0629 const struct iio_chan_spec *chan, enum iio_event_type type,
0630 enum iio_event_direction dir, int state)
0631 {
0632 struct us5182d_data *data = iio_priv(indio_dev);
0633 int ret;
0634 u16 new_th;
0635
0636 mutex_lock(&data->lock);
0637
0638 switch (dir) {
0639 case IIO_EV_DIR_RISING:
0640 if (data->rising_en == state) {
0641 mutex_unlock(&data->lock);
0642 return 0;
0643 }
0644 new_th = US5182D_PXH_TH_DISABLE;
0645 if (state) {
0646 data->power_mode = US5182D_CONTINUOUS;
0647 ret = us5182d_set_power_state(data, true);
0648 if (ret < 0)
0649 goto err;
0650 ret = us5182d_px_enable(data);
0651 if (ret < 0)
0652 goto err_poweroff;
0653 new_th = data->px_high_th;
0654 }
0655 ret = us5182d_setup_prox(indio_dev, dir, new_th);
0656 if (ret < 0)
0657 goto err_poweroff;
0658 data->rising_en = state;
0659 break;
0660 case IIO_EV_DIR_FALLING:
0661 if (data->falling_en == state) {
0662 mutex_unlock(&data->lock);
0663 return 0;
0664 }
0665 new_th = US5182D_PXL_TH_DISABLE;
0666 if (state) {
0667 data->power_mode = US5182D_CONTINUOUS;
0668 ret = us5182d_set_power_state(data, true);
0669 if (ret < 0)
0670 goto err;
0671 ret = us5182d_px_enable(data);
0672 if (ret < 0)
0673 goto err_poweroff;
0674 new_th = data->px_low_th;
0675 }
0676 ret = us5182d_setup_prox(indio_dev, dir, new_th);
0677 if (ret < 0)
0678 goto err_poweroff;
0679 data->falling_en = state;
0680 break;
0681 default:
0682 ret = -EINVAL;
0683 goto err;
0684 }
0685
0686 if (!state) {
0687 ret = us5182d_set_power_state(data, false);
0688 if (ret < 0)
0689 goto err;
0690 }
0691
0692 if (!data->falling_en && !data->rising_en && !data->default_continuous)
0693 data->power_mode = US5182D_ONESHOT;
0694
0695 mutex_unlock(&data->lock);
0696 return 0;
0697
0698 err_poweroff:
0699 if (state)
0700 us5182d_set_power_state(data, false);
0701 err:
0702 mutex_unlock(&data->lock);
0703 return ret;
0704 }
0705
0706 static const struct iio_info us5182d_info = {
0707 .read_raw = us5182d_read_raw,
0708 .write_raw = us5182d_write_raw,
0709 .attrs = &us5182d_attr_group,
0710 .read_event_value = &us5182d_read_thresh,
0711 .write_event_value = &us5182d_write_thresh,
0712 .read_event_config = &us5182d_read_event_config,
0713 .write_event_config = &us5182d_write_event_config,
0714 };
0715
0716 static int us5182d_reset(struct iio_dev *indio_dev)
0717 {
0718 struct us5182d_data *data = iio_priv(indio_dev);
0719
0720 return i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG3,
0721 US5182D_RESET_CHIP);
0722 }
0723
0724 static int us5182d_init(struct iio_dev *indio_dev)
0725 {
0726 struct us5182d_data *data = iio_priv(indio_dev);
0727 int i, ret;
0728
0729 ret = us5182d_reset(indio_dev);
0730 if (ret < 0)
0731 return ret;
0732
0733 data->opmode = 0;
0734 data->power_mode = US5182D_CONTINUOUS;
0735 data->px_low_th = US5182D_REG_PXL_TH_DEFAULT;
0736 data->px_high_th = US5182D_REG_PXH_TH_DEFAULT;
0737
0738 for (i = 0; i < ARRAY_SIZE(us5182d_regvals); i++) {
0739 ret = i2c_smbus_write_byte_data(data->client,
0740 us5182d_regvals[i].reg,
0741 us5182d_regvals[i].val);
0742 if (ret < 0)
0743 return ret;
0744 }
0745
0746 data->als_enabled = true;
0747 data->px_enabled = true;
0748
0749 if (!data->default_continuous) {
0750 ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
0751 if (ret < 0)
0752 return ret;
0753 data->power_mode = US5182D_ONESHOT;
0754 }
0755
0756 return ret;
0757 }
0758
0759 static void us5182d_get_platform_data(struct iio_dev *indio_dev)
0760 {
0761 struct us5182d_data *data = iio_priv(indio_dev);
0762
0763 if (device_property_read_u32(&data->client->dev, "upisemi,glass-coef",
0764 &data->ga))
0765 data->ga = US5182D_GA_RESOLUTION;
0766 if (device_property_read_u16_array(&data->client->dev,
0767 "upisemi,dark-ths",
0768 data->us5182d_dark_ths,
0769 ARRAY_SIZE(us5182d_dark_ths_vals)))
0770 data->us5182d_dark_ths = us5182d_dark_ths_vals;
0771 if (device_property_read_u8(&data->client->dev,
0772 "upisemi,upper-dark-gain",
0773 &data->upper_dark_gain))
0774 data->upper_dark_gain = US5182D_REG_AUTO_HDARK_GAIN_DEFAULT;
0775 if (device_property_read_u8(&data->client->dev,
0776 "upisemi,lower-dark-gain",
0777 &data->lower_dark_gain))
0778 data->lower_dark_gain = US5182D_REG_AUTO_LDARK_GAIN_DEFAULT;
0779 data->default_continuous = device_property_read_bool(&data->client->dev,
0780 "upisemi,continuous");
0781 }
0782
0783 static int us5182d_dark_gain_config(struct iio_dev *indio_dev)
0784 {
0785 struct us5182d_data *data = iio_priv(indio_dev);
0786 int ret;
0787
0788 ret = us5182d_update_dark_th(data, US5182D_CFG1_AGAIN_DEFAULT);
0789 if (ret < 0)
0790 return ret;
0791
0792 ret = i2c_smbus_write_byte_data(data->client,
0793 US5182D_REG_AUTO_LDARK_GAIN,
0794 data->lower_dark_gain);
0795 if (ret < 0)
0796 return ret;
0797
0798 ret = i2c_smbus_write_byte_data(data->client,
0799 US5182D_REG_AUTO_HDARK_GAIN,
0800 data->upper_dark_gain);
0801 if (ret < 0)
0802 return ret;
0803
0804 return i2c_smbus_write_byte_data(data->client, US5182D_REG_DARK_AUTO_EN,
0805 US5182D_REG_DARK_AUTO_EN_DEFAULT);
0806 }
0807
0808 static irqreturn_t us5182d_irq_thread_handler(int irq, void *private)
0809 {
0810 struct iio_dev *indio_dev = private;
0811 struct us5182d_data *data = iio_priv(indio_dev);
0812 enum iio_event_direction dir;
0813 int ret;
0814 u64 ev;
0815
0816 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CFG0);
0817 if (ret < 0) {
0818 dev_err(&data->client->dev, "i2c transfer error in irq\n");
0819 return IRQ_HANDLED;
0820 }
0821
0822 dir = ret & US5182D_CFG0_PROX ? IIO_EV_DIR_RISING : IIO_EV_DIR_FALLING;
0823 ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 1, IIO_EV_TYPE_THRESH, dir);
0824
0825 iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
0826
0827 ret = i2c_smbus_write_byte_data(data->client, US5182D_REG_CFG0,
0828 ret & ~US5182D_CFG0_PX_IRQ);
0829 if (ret < 0)
0830 dev_err(&data->client->dev, "i2c transfer error in irq\n");
0831
0832 return IRQ_HANDLED;
0833 }
0834
0835 static int us5182d_probe(struct i2c_client *client,
0836 const struct i2c_device_id *id)
0837 {
0838 struct us5182d_data *data;
0839 struct iio_dev *indio_dev;
0840 int ret;
0841
0842 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0843 if (!indio_dev)
0844 return -ENOMEM;
0845
0846 data = iio_priv(indio_dev);
0847 i2c_set_clientdata(client, indio_dev);
0848 data->client = client;
0849
0850 mutex_init(&data->lock);
0851
0852 indio_dev->info = &us5182d_info;
0853 indio_dev->name = US5182D_DRV_NAME;
0854 indio_dev->channels = us5182d_channels;
0855 indio_dev->num_channels = ARRAY_SIZE(us5182d_channels);
0856 indio_dev->modes = INDIO_DIRECT_MODE;
0857
0858 ret = i2c_smbus_read_byte_data(data->client, US5182D_REG_CHIPID);
0859 if (ret != US5182D_CHIPID) {
0860 dev_err(&data->client->dev,
0861 "Failed to detect US5182 light chip\n");
0862 return (ret < 0) ? ret : -ENODEV;
0863 }
0864
0865 if (client->irq > 0) {
0866 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
0867 us5182d_irq_thread_handler,
0868 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0869 "us5182d-irq", indio_dev);
0870 if (ret < 0)
0871 return ret;
0872 } else
0873 dev_warn(&client->dev, "no valid irq found\n");
0874
0875 us5182d_get_platform_data(indio_dev);
0876 ret = us5182d_init(indio_dev);
0877 if (ret < 0)
0878 return ret;
0879
0880 ret = us5182d_dark_gain_config(indio_dev);
0881 if (ret < 0)
0882 goto out_err;
0883
0884 if (data->default_continuous) {
0885 ret = pm_runtime_set_active(&client->dev);
0886 if (ret < 0)
0887 goto out_err;
0888 }
0889
0890 pm_runtime_enable(&client->dev);
0891 pm_runtime_set_autosuspend_delay(&client->dev,
0892 US5182D_SLEEP_MS);
0893 pm_runtime_use_autosuspend(&client->dev);
0894
0895 ret = iio_device_register(indio_dev);
0896 if (ret < 0)
0897 goto out_err;
0898
0899 return 0;
0900
0901 out_err:
0902 us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
0903 return ret;
0904
0905 }
0906
0907 static int us5182d_remove(struct i2c_client *client)
0908 {
0909 struct us5182d_data *data = iio_priv(i2c_get_clientdata(client));
0910 int ret;
0911
0912 iio_device_unregister(i2c_get_clientdata(client));
0913
0914 pm_runtime_disable(&client->dev);
0915 pm_runtime_set_suspended(&client->dev);
0916
0917 ret = us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
0918 if (ret)
0919 dev_warn(&client->dev, "Failed to shut down (%pe)\n",
0920 ERR_PTR(ret));
0921
0922 return 0;
0923 }
0924
0925 static int us5182d_suspend(struct device *dev)
0926 {
0927 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0928 struct us5182d_data *data = iio_priv(indio_dev);
0929
0930 if (data->power_mode == US5182D_CONTINUOUS)
0931 return us5182d_shutdown_en(data, US5182D_CFG0_SHUTDOWN_EN);
0932
0933 return 0;
0934 }
0935
0936 static int us5182d_resume(struct device *dev)
0937 {
0938 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0939 struct us5182d_data *data = iio_priv(indio_dev);
0940
0941 if (data->power_mode == US5182D_CONTINUOUS)
0942 return us5182d_shutdown_en(data,
0943 ~US5182D_CFG0_SHUTDOWN_EN & 0xff);
0944
0945 return 0;
0946 }
0947
0948 static const struct dev_pm_ops us5182d_pm_ops = {
0949 SYSTEM_SLEEP_PM_OPS(us5182d_suspend, us5182d_resume)
0950 RUNTIME_PM_OPS(us5182d_suspend, us5182d_resume, NULL)
0951 };
0952
0953 static const struct acpi_device_id us5182d_acpi_match[] = {
0954 { "USD5182", 0 },
0955 {}
0956 };
0957
0958 MODULE_DEVICE_TABLE(acpi, us5182d_acpi_match);
0959
0960 static const struct i2c_device_id us5182d_id[] = {
0961 { "usd5182", 0 },
0962 {}
0963 };
0964
0965 MODULE_DEVICE_TABLE(i2c, us5182d_id);
0966
0967 static const struct of_device_id us5182d_of_match[] = {
0968 { .compatible = "upisemi,usd5182" },
0969 {}
0970 };
0971 MODULE_DEVICE_TABLE(of, us5182d_of_match);
0972
0973 static struct i2c_driver us5182d_driver = {
0974 .driver = {
0975 .name = US5182D_DRV_NAME,
0976 .pm = pm_ptr(&us5182d_pm_ops),
0977 .of_match_table = us5182d_of_match,
0978 .acpi_match_table = ACPI_PTR(us5182d_acpi_match),
0979 },
0980 .probe = us5182d_probe,
0981 .remove = us5182d_remove,
0982 .id_table = us5182d_id,
0983
0984 };
0985 module_i2c_driver(us5182d_driver);
0986
0987 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
0988 MODULE_DESCRIPTION("Driver for us5182d Proximity and Light Sensor");
0989 MODULE_LICENSE("GPL v2");