0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/i2c.h>
0012 #include <linux/errno.h>
0013 #include <linux/delay.h>
0014 #include <linux/string.h>
0015 #include <linux/mutex.h>
0016 #include <linux/unistd.h>
0017 #include <linux/slab.h>
0018 #include <linux/module.h>
0019 #include <linux/iio/iio.h>
0020 #include <linux/iio/sysfs.h>
0021 #include <linux/pm_runtime.h>
0022
0023
0024 #define TSL2583_CNTRL 0x00
0025 #define TSL2583_ALS_TIME 0X01
0026 #define TSL2583_INTERRUPT 0x02
0027 #define TSL2583_GAIN 0x07
0028 #define TSL2583_REVID 0x11
0029 #define TSL2583_CHIPID 0x12
0030 #define TSL2583_ALS_CHAN0LO 0x14
0031 #define TSL2583_ALS_CHAN0HI 0x15
0032 #define TSL2583_ALS_CHAN1LO 0x16
0033 #define TSL2583_ALS_CHAN1HI 0x17
0034 #define TSL2583_TMR_LO 0x18
0035 #define TSL2583_TMR_HI 0x19
0036
0037
0038 #define TSL2583_CMD_REG 0x80
0039 #define TSL2583_CMD_SPL_FN 0x60
0040 #define TSL2583_CMD_ALS_INT_CLR 0x01
0041
0042
0043 #define TSL2583_CNTL_ADC_ENBL 0x02
0044 #define TSL2583_CNTL_PWR_OFF 0x00
0045 #define TSL2583_CNTL_PWR_ON 0x01
0046
0047
0048 #define TSL2583_STA_ADC_VALID 0x01
0049 #define TSL2583_STA_ADC_INTR 0x10
0050
0051
0052 #define TSL2583_LUX_CALC_OVER_FLOW 65535
0053
0054 #define TSL2583_INTERRUPT_DISABLED 0x00
0055
0056 #define TSL2583_CHIP_ID 0x90
0057 #define TSL2583_CHIP_ID_MASK 0xf0
0058
0059 #define TSL2583_POWER_OFF_DELAY_MS 2000
0060
0061
0062 struct tsl2583_als_info {
0063 u16 als_ch0;
0064 u16 als_ch1;
0065 u16 lux;
0066 };
0067
0068 struct tsl2583_lux {
0069 unsigned int ratio;
0070 unsigned int ch0;
0071 unsigned int ch1;
0072 };
0073
0074 static const struct tsl2583_lux tsl2583_default_lux[] = {
0075 { 9830, 8520, 15729 },
0076 { 12452, 10807, 23344 },
0077 { 14746, 6383, 11705 },
0078 { 17695, 4063, 6554 },
0079 { 0, 0, 0 }
0080 };
0081
0082 #define TSL2583_MAX_LUX_TABLE_ENTRIES 11
0083
0084 struct tsl2583_settings {
0085 int als_time;
0086 int als_gain;
0087 int als_gain_trim;
0088 int als_cal_target;
0089
0090
0091
0092
0093
0094
0095 struct tsl2583_lux als_device_lux[TSL2583_MAX_LUX_TABLE_ENTRIES];
0096 };
0097
0098 struct tsl2583_chip {
0099 struct mutex als_mutex;
0100 struct i2c_client *client;
0101 struct tsl2583_als_info als_cur_info;
0102 struct tsl2583_settings als_settings;
0103 int als_time_scale;
0104 int als_saturation;
0105 };
0106
0107 struct gainadj {
0108 s16 ch0;
0109 s16 ch1;
0110 s16 mean;
0111 };
0112
0113
0114 static const struct gainadj gainadj[] = {
0115 { 1, 1, 1 },
0116 { 8, 8, 8 },
0117 { 16, 16, 16 },
0118 { 107, 115, 111 }
0119 };
0120
0121
0122
0123
0124
0125 static void tsl2583_defaults(struct tsl2583_chip *chip)
0126 {
0127
0128
0129
0130
0131 chip->als_settings.als_time = 100;
0132
0133
0134
0135
0136
0137 chip->als_settings.als_gain = 0;
0138
0139
0140 chip->als_settings.als_gain_trim = 1000;
0141
0142
0143 chip->als_settings.als_cal_target = 130;
0144
0145
0146 memcpy(chip->als_settings.als_device_lux, tsl2583_default_lux,
0147 sizeof(tsl2583_default_lux));
0148 }
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 static int tsl2583_get_lux(struct iio_dev *indio_dev)
0164 {
0165 u16 ch0, ch1;
0166 u32 lux;
0167 u64 lux64;
0168 u32 ratio;
0169 u8 buf[5];
0170 struct tsl2583_lux *p;
0171 struct tsl2583_chip *chip = iio_priv(indio_dev);
0172 int i, ret;
0173
0174 ret = i2c_smbus_read_byte_data(chip->client, TSL2583_CMD_REG);
0175 if (ret < 0) {
0176 dev_err(&chip->client->dev, "%s: failed to read CMD_REG register\n",
0177 __func__);
0178 goto done;
0179 }
0180
0181
0182 if (!(ret & TSL2583_STA_ADC_INTR)) {
0183 dev_err(&chip->client->dev, "%s: data not valid; returning last value\n",
0184 __func__);
0185 ret = chip->als_cur_info.lux;
0186 goto done;
0187 }
0188
0189 for (i = 0; i < 4; i++) {
0190 int reg = TSL2583_CMD_REG | (TSL2583_ALS_CHAN0LO + i);
0191
0192 ret = i2c_smbus_read_byte_data(chip->client, reg);
0193 if (ret < 0) {
0194 dev_err(&chip->client->dev, "%s: failed to read register %x\n",
0195 __func__, reg);
0196 goto done;
0197 }
0198 buf[i] = ret;
0199 }
0200
0201
0202
0203
0204
0205
0206 ret = i2c_smbus_write_byte(chip->client,
0207 (TSL2583_CMD_REG | TSL2583_CMD_SPL_FN |
0208 TSL2583_CMD_ALS_INT_CLR));
0209 if (ret < 0) {
0210 dev_err(&chip->client->dev, "%s: failed to clear the interrupt bit\n",
0211 __func__);
0212 goto done;
0213 }
0214
0215
0216 ch0 = le16_to_cpup((const __le16 *)&buf[0]);
0217 ch1 = le16_to_cpup((const __le16 *)&buf[2]);
0218
0219 chip->als_cur_info.als_ch0 = ch0;
0220 chip->als_cur_info.als_ch1 = ch1;
0221
0222 if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation))
0223 goto return_max;
0224
0225 if (!ch0) {
0226
0227
0228
0229
0230
0231 ret = 0;
0232 chip->als_cur_info.lux = 0;
0233 goto done;
0234 }
0235
0236
0237 ratio = (ch1 << 15) / ch0;
0238
0239
0240 for (p = (struct tsl2583_lux *)chip->als_settings.als_device_lux;
0241 p->ratio != 0 && p->ratio < ratio; p++)
0242 ;
0243
0244 if (p->ratio == 0) {
0245 lux = 0;
0246 } else {
0247 u32 ch0lux, ch1lux;
0248
0249 ch0lux = ((ch0 * p->ch0) +
0250 (gainadj[chip->als_settings.als_gain].ch0 >> 1))
0251 / gainadj[chip->als_settings.als_gain].ch0;
0252 ch1lux = ((ch1 * p->ch1) +
0253 (gainadj[chip->als_settings.als_gain].ch1 >> 1))
0254 / gainadj[chip->als_settings.als_gain].ch1;
0255
0256
0257 if (ch1lux > ch0lux) {
0258 dev_dbg(&chip->client->dev, "%s: No Data - Returning 0\n",
0259 __func__);
0260 ret = 0;
0261 chip->als_cur_info.lux = 0;
0262 goto done;
0263 }
0264
0265 lux = ch0lux - ch1lux;
0266 }
0267
0268
0269 if (chip->als_time_scale == 0)
0270 lux = 0;
0271 else
0272 lux = (lux + (chip->als_time_scale >> 1)) /
0273 chip->als_time_scale;
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284 lux64 = lux;
0285 lux64 = lux64 * chip->als_settings.als_gain_trim;
0286 lux64 >>= 13;
0287 lux = lux64;
0288 lux = DIV_ROUND_CLOSEST(lux, 1000);
0289
0290 if (lux > TSL2583_LUX_CALC_OVER_FLOW) {
0291 return_max:
0292 lux = TSL2583_LUX_CALC_OVER_FLOW;
0293 }
0294
0295
0296 chip->als_cur_info.lux = lux;
0297 ret = lux;
0298
0299 done:
0300 return ret;
0301 }
0302
0303
0304
0305
0306
0307
0308 static int tsl2583_als_calibrate(struct iio_dev *indio_dev)
0309 {
0310 struct tsl2583_chip *chip = iio_priv(indio_dev);
0311 unsigned int gain_trim_val;
0312 int ret;
0313 int lux_val;
0314
0315 ret = i2c_smbus_read_byte_data(chip->client,
0316 TSL2583_CMD_REG | TSL2583_CNTRL);
0317 if (ret < 0) {
0318 dev_err(&chip->client->dev,
0319 "%s: failed to read from the CNTRL register\n",
0320 __func__);
0321 return ret;
0322 }
0323
0324 if ((ret & (TSL2583_CNTL_ADC_ENBL | TSL2583_CNTL_PWR_ON))
0325 != (TSL2583_CNTL_ADC_ENBL | TSL2583_CNTL_PWR_ON)) {
0326 dev_err(&chip->client->dev,
0327 "%s: Device is not powered on and/or ADC is not enabled\n",
0328 __func__);
0329 return -EINVAL;
0330 } else if ((ret & TSL2583_STA_ADC_VALID) != TSL2583_STA_ADC_VALID) {
0331 dev_err(&chip->client->dev,
0332 "%s: The two ADC channels have not completed an integration cycle\n",
0333 __func__);
0334 return -ENODATA;
0335 }
0336
0337 lux_val = tsl2583_get_lux(indio_dev);
0338 if (lux_val < 0) {
0339 dev_err(&chip->client->dev, "%s: failed to get lux\n",
0340 __func__);
0341 return lux_val;
0342 }
0343
0344
0345 if (lux_val == 0) {
0346 dev_err(&chip->client->dev,
0347 "%s: lux_val of 0 will produce out of range trim_value\n",
0348 __func__);
0349 return -ENODATA;
0350 }
0351
0352 gain_trim_val = (unsigned int)(((chip->als_settings.als_cal_target)
0353 * chip->als_settings.als_gain_trim) / lux_val);
0354 if ((gain_trim_val < 250) || (gain_trim_val > 4000)) {
0355 dev_err(&chip->client->dev,
0356 "%s: trim_val of %d is not within the range [250, 4000]\n",
0357 __func__, gain_trim_val);
0358 return -ENODATA;
0359 }
0360
0361 chip->als_settings.als_gain_trim = (int)gain_trim_val;
0362
0363 return 0;
0364 }
0365
0366 static int tsl2583_set_als_time(struct tsl2583_chip *chip)
0367 {
0368 int als_count, als_time, ret;
0369 u8 val;
0370
0371
0372 als_count = DIV_ROUND_CLOSEST(chip->als_settings.als_time * 100, 270);
0373 if (!als_count)
0374 als_count = 1;
0375
0376
0377 als_time = DIV_ROUND_CLOSEST(als_count * 27, 10);
0378
0379 val = 256 - als_count;
0380 ret = i2c_smbus_write_byte_data(chip->client,
0381 TSL2583_CMD_REG | TSL2583_ALS_TIME,
0382 val);
0383 if (ret < 0) {
0384 dev_err(&chip->client->dev, "%s: failed to set the als time to %d\n",
0385 __func__, val);
0386 return ret;
0387 }
0388
0389
0390 chip->als_saturation = als_count * 922;
0391 chip->als_time_scale = DIV_ROUND_CLOSEST(als_time, 50);
0392
0393 return ret;
0394 }
0395
0396 static int tsl2583_set_als_gain(struct tsl2583_chip *chip)
0397 {
0398 int ret;
0399
0400
0401 ret = i2c_smbus_write_byte_data(chip->client,
0402 TSL2583_CMD_REG | TSL2583_GAIN,
0403 chip->als_settings.als_gain);
0404 if (ret < 0)
0405 dev_err(&chip->client->dev,
0406 "%s: failed to set the gain to %d\n", __func__,
0407 chip->als_settings.als_gain);
0408
0409 return ret;
0410 }
0411
0412 static int tsl2583_set_power_state(struct tsl2583_chip *chip, u8 state)
0413 {
0414 int ret;
0415
0416 ret = i2c_smbus_write_byte_data(chip->client,
0417 TSL2583_CMD_REG | TSL2583_CNTRL, state);
0418 if (ret < 0)
0419 dev_err(&chip->client->dev,
0420 "%s: failed to set the power state to %d\n", __func__,
0421 state);
0422
0423 return ret;
0424 }
0425
0426
0427
0428
0429
0430 static int tsl2583_chip_init_and_power_on(struct iio_dev *indio_dev)
0431 {
0432 struct tsl2583_chip *chip = iio_priv(indio_dev);
0433 int ret;
0434
0435
0436 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON);
0437 if (ret < 0)
0438 return ret;
0439
0440 ret = i2c_smbus_write_byte_data(chip->client,
0441 TSL2583_CMD_REG | TSL2583_INTERRUPT,
0442 TSL2583_INTERRUPT_DISABLED);
0443 if (ret < 0) {
0444 dev_err(&chip->client->dev,
0445 "%s: failed to disable interrupts\n", __func__);
0446 return ret;
0447 }
0448
0449 ret = tsl2583_set_als_time(chip);
0450 if (ret < 0)
0451 return ret;
0452
0453 ret = tsl2583_set_als_gain(chip);
0454 if (ret < 0)
0455 return ret;
0456
0457 usleep_range(3000, 3500);
0458
0459 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_ON |
0460 TSL2583_CNTL_ADC_ENBL);
0461 if (ret < 0)
0462 return ret;
0463
0464 return ret;
0465 }
0466
0467
0468
0469 static ssize_t in_illuminance_input_target_show(struct device *dev,
0470 struct device_attribute *attr,
0471 char *buf)
0472 {
0473 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0474 struct tsl2583_chip *chip = iio_priv(indio_dev);
0475 int ret;
0476
0477 mutex_lock(&chip->als_mutex);
0478 ret = sprintf(buf, "%d\n", chip->als_settings.als_cal_target);
0479 mutex_unlock(&chip->als_mutex);
0480
0481 return ret;
0482 }
0483
0484 static ssize_t in_illuminance_input_target_store(struct device *dev,
0485 struct device_attribute *attr,
0486 const char *buf, size_t len)
0487 {
0488 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0489 struct tsl2583_chip *chip = iio_priv(indio_dev);
0490 int value;
0491
0492 if (kstrtoint(buf, 0, &value) || !value)
0493 return -EINVAL;
0494
0495 mutex_lock(&chip->als_mutex);
0496 chip->als_settings.als_cal_target = value;
0497 mutex_unlock(&chip->als_mutex);
0498
0499 return len;
0500 }
0501
0502 static ssize_t in_illuminance_calibrate_store(struct device *dev,
0503 struct device_attribute *attr,
0504 const char *buf, size_t len)
0505 {
0506 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0507 struct tsl2583_chip *chip = iio_priv(indio_dev);
0508 int value, ret;
0509
0510 if (kstrtoint(buf, 0, &value) || value != 1)
0511 return -EINVAL;
0512
0513 mutex_lock(&chip->als_mutex);
0514
0515 ret = tsl2583_als_calibrate(indio_dev);
0516 if (ret < 0)
0517 goto done;
0518
0519 ret = len;
0520 done:
0521 mutex_unlock(&chip->als_mutex);
0522
0523 return ret;
0524 }
0525
0526 static ssize_t in_illuminance_lux_table_show(struct device *dev,
0527 struct device_attribute *attr,
0528 char *buf)
0529 {
0530 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0531 struct tsl2583_chip *chip = iio_priv(indio_dev);
0532 unsigned int i;
0533 int offset = 0;
0534
0535 for (i = 0; i < ARRAY_SIZE(chip->als_settings.als_device_lux); i++) {
0536 offset += sprintf(buf + offset, "%u,%u,%u,",
0537 chip->als_settings.als_device_lux[i].ratio,
0538 chip->als_settings.als_device_lux[i].ch0,
0539 chip->als_settings.als_device_lux[i].ch1);
0540 if (chip->als_settings.als_device_lux[i].ratio == 0) {
0541
0542
0543
0544
0545 offset--;
0546 break;
0547 }
0548 }
0549
0550 offset += sprintf(buf + offset, "\n");
0551
0552 return offset;
0553 }
0554
0555 static ssize_t in_illuminance_lux_table_store(struct device *dev,
0556 struct device_attribute *attr,
0557 const char *buf, size_t len)
0558 {
0559 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0560 struct tsl2583_chip *chip = iio_priv(indio_dev);
0561 const unsigned int max_ints = TSL2583_MAX_LUX_TABLE_ENTRIES * 3;
0562 int value[TSL2583_MAX_LUX_TABLE_ENTRIES * 3 + 1];
0563 int ret = -EINVAL;
0564 unsigned int n;
0565
0566 mutex_lock(&chip->als_mutex);
0567
0568 get_options(buf, ARRAY_SIZE(value), value);
0569
0570
0571
0572
0573
0574
0575
0576 n = value[0];
0577 if ((n % 3) || n < 6 || n > max_ints) {
0578 dev_err(dev,
0579 "%s: The number of entries in the lux table must be a multiple of 3 and within the range [6, %d]\n",
0580 __func__, max_ints);
0581 goto done;
0582 }
0583 if ((value[n - 2] | value[n - 1] | value[n]) != 0) {
0584 dev_err(dev, "%s: The last 3 entries in the lux table must be zeros.\n",
0585 __func__);
0586 goto done;
0587 }
0588
0589 memcpy(chip->als_settings.als_device_lux, &value[1],
0590 value[0] * sizeof(value[1]));
0591
0592 ret = len;
0593
0594 done:
0595 mutex_unlock(&chip->als_mutex);
0596
0597 return ret;
0598 }
0599
0600 static IIO_CONST_ATTR(in_illuminance_calibscale_available, "1 8 16 111");
0601 static IIO_CONST_ATTR(in_illuminance_integration_time_available,
0602 "0.050 0.100 0.150 0.200 0.250 0.300 0.350 0.400 0.450 0.500 0.550 0.600 0.650");
0603 static IIO_DEVICE_ATTR_RW(in_illuminance_input_target, 0);
0604 static IIO_DEVICE_ATTR_WO(in_illuminance_calibrate, 0);
0605 static IIO_DEVICE_ATTR_RW(in_illuminance_lux_table, 0);
0606
0607 static struct attribute *sysfs_attrs_ctrl[] = {
0608 &iio_const_attr_in_illuminance_calibscale_available.dev_attr.attr,
0609 &iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
0610 &iio_dev_attr_in_illuminance_input_target.dev_attr.attr,
0611 &iio_dev_attr_in_illuminance_calibrate.dev_attr.attr,
0612 &iio_dev_attr_in_illuminance_lux_table.dev_attr.attr,
0613 NULL
0614 };
0615
0616 static const struct attribute_group tsl2583_attribute_group = {
0617 .attrs = sysfs_attrs_ctrl,
0618 };
0619
0620 static const struct iio_chan_spec tsl2583_channels[] = {
0621 {
0622 .type = IIO_LIGHT,
0623 .modified = 1,
0624 .channel2 = IIO_MOD_LIGHT_IR,
0625 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0626 },
0627 {
0628 .type = IIO_LIGHT,
0629 .modified = 1,
0630 .channel2 = IIO_MOD_LIGHT_BOTH,
0631 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0632 },
0633 {
0634 .type = IIO_LIGHT,
0635 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
0636 BIT(IIO_CHAN_INFO_CALIBBIAS) |
0637 BIT(IIO_CHAN_INFO_CALIBSCALE) |
0638 BIT(IIO_CHAN_INFO_INT_TIME),
0639 },
0640 };
0641
0642 static int tsl2583_set_pm_runtime_busy(struct tsl2583_chip *chip, bool on)
0643 {
0644 int ret;
0645
0646 if (on) {
0647 ret = pm_runtime_resume_and_get(&chip->client->dev);
0648 } else {
0649 pm_runtime_mark_last_busy(&chip->client->dev);
0650 ret = pm_runtime_put_autosuspend(&chip->client->dev);
0651 }
0652
0653 return ret;
0654 }
0655
0656 static int tsl2583_read_raw(struct iio_dev *indio_dev,
0657 struct iio_chan_spec const *chan,
0658 int *val, int *val2, long mask)
0659 {
0660 struct tsl2583_chip *chip = iio_priv(indio_dev);
0661 int ret, pm_ret;
0662
0663 ret = tsl2583_set_pm_runtime_busy(chip, true);
0664 if (ret < 0)
0665 return ret;
0666
0667 mutex_lock(&chip->als_mutex);
0668
0669 ret = -EINVAL;
0670 switch (mask) {
0671 case IIO_CHAN_INFO_RAW:
0672 if (chan->type == IIO_LIGHT) {
0673 ret = tsl2583_get_lux(indio_dev);
0674 if (ret < 0)
0675 goto read_done;
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686 if (chan->channel2 == IIO_MOD_LIGHT_BOTH)
0687 *val = chip->als_cur_info.als_ch0;
0688 else
0689 *val = chip->als_cur_info.als_ch1;
0690
0691 ret = IIO_VAL_INT;
0692 }
0693 break;
0694 case IIO_CHAN_INFO_PROCESSED:
0695 if (chan->type == IIO_LIGHT) {
0696 ret = tsl2583_get_lux(indio_dev);
0697 if (ret < 0)
0698 goto read_done;
0699
0700 *val = ret;
0701 ret = IIO_VAL_INT;
0702 }
0703 break;
0704 case IIO_CHAN_INFO_CALIBBIAS:
0705 if (chan->type == IIO_LIGHT) {
0706 *val = chip->als_settings.als_gain_trim;
0707 ret = IIO_VAL_INT;
0708 }
0709 break;
0710 case IIO_CHAN_INFO_CALIBSCALE:
0711 if (chan->type == IIO_LIGHT) {
0712 *val = gainadj[chip->als_settings.als_gain].mean;
0713 ret = IIO_VAL_INT;
0714 }
0715 break;
0716 case IIO_CHAN_INFO_INT_TIME:
0717 if (chan->type == IIO_LIGHT) {
0718 *val = 0;
0719 *val2 = chip->als_settings.als_time;
0720 ret = IIO_VAL_INT_PLUS_MICRO;
0721 }
0722 break;
0723 default:
0724 break;
0725 }
0726
0727 read_done:
0728 mutex_unlock(&chip->als_mutex);
0729
0730 if (ret < 0) {
0731 tsl2583_set_pm_runtime_busy(chip, false);
0732 return ret;
0733 }
0734
0735
0736
0737
0738
0739
0740 pm_ret = tsl2583_set_pm_runtime_busy(chip, false);
0741 if (pm_ret < 0)
0742 return pm_ret;
0743
0744 return ret;
0745 }
0746
0747 static int tsl2583_write_raw(struct iio_dev *indio_dev,
0748 struct iio_chan_spec const *chan,
0749 int val, int val2, long mask)
0750 {
0751 struct tsl2583_chip *chip = iio_priv(indio_dev);
0752 int ret;
0753
0754 ret = tsl2583_set_pm_runtime_busy(chip, true);
0755 if (ret < 0)
0756 return ret;
0757
0758 mutex_lock(&chip->als_mutex);
0759
0760 ret = -EINVAL;
0761 switch (mask) {
0762 case IIO_CHAN_INFO_CALIBBIAS:
0763 if (chan->type == IIO_LIGHT) {
0764 chip->als_settings.als_gain_trim = val;
0765 ret = 0;
0766 }
0767 break;
0768 case IIO_CHAN_INFO_CALIBSCALE:
0769 if (chan->type == IIO_LIGHT) {
0770 unsigned int i;
0771
0772 for (i = 0; i < ARRAY_SIZE(gainadj); i++) {
0773 if (gainadj[i].mean == val) {
0774 chip->als_settings.als_gain = i;
0775 ret = tsl2583_set_als_gain(chip);
0776 break;
0777 }
0778 }
0779 }
0780 break;
0781 case IIO_CHAN_INFO_INT_TIME:
0782 if (chan->type == IIO_LIGHT && !val && val2 >= 50 &&
0783 val2 <= 650 && !(val2 % 50)) {
0784 chip->als_settings.als_time = val2;
0785 ret = tsl2583_set_als_time(chip);
0786 }
0787 break;
0788 default:
0789 break;
0790 }
0791
0792 mutex_unlock(&chip->als_mutex);
0793
0794 if (ret < 0) {
0795 tsl2583_set_pm_runtime_busy(chip, false);
0796 return ret;
0797 }
0798
0799 ret = tsl2583_set_pm_runtime_busy(chip, false);
0800 if (ret < 0)
0801 return ret;
0802
0803 return ret;
0804 }
0805
0806 static const struct iio_info tsl2583_info = {
0807 .attrs = &tsl2583_attribute_group,
0808 .read_raw = tsl2583_read_raw,
0809 .write_raw = tsl2583_write_raw,
0810 };
0811
0812 static int tsl2583_probe(struct i2c_client *clientp,
0813 const struct i2c_device_id *idp)
0814 {
0815 int ret;
0816 struct tsl2583_chip *chip;
0817 struct iio_dev *indio_dev;
0818
0819 if (!i2c_check_functionality(clientp->adapter,
0820 I2C_FUNC_SMBUS_BYTE_DATA)) {
0821 dev_err(&clientp->dev, "%s: i2c smbus byte data functionality is unsupported\n",
0822 __func__);
0823 return -EOPNOTSUPP;
0824 }
0825
0826 indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
0827 if (!indio_dev)
0828 return -ENOMEM;
0829
0830 chip = iio_priv(indio_dev);
0831 chip->client = clientp;
0832 i2c_set_clientdata(clientp, indio_dev);
0833
0834 mutex_init(&chip->als_mutex);
0835
0836 ret = i2c_smbus_read_byte_data(clientp,
0837 TSL2583_CMD_REG | TSL2583_CHIPID);
0838 if (ret < 0) {
0839 dev_err(&clientp->dev,
0840 "%s: failed to read the chip ID register\n", __func__);
0841 return ret;
0842 }
0843
0844 if ((ret & TSL2583_CHIP_ID_MASK) != TSL2583_CHIP_ID) {
0845 dev_err(&clientp->dev, "%s: received an unknown chip ID %x\n",
0846 __func__, ret);
0847 return -EINVAL;
0848 }
0849
0850 indio_dev->info = &tsl2583_info;
0851 indio_dev->channels = tsl2583_channels;
0852 indio_dev->num_channels = ARRAY_SIZE(tsl2583_channels);
0853 indio_dev->modes = INDIO_DIRECT_MODE;
0854 indio_dev->name = chip->client->name;
0855
0856 pm_runtime_enable(&clientp->dev);
0857 pm_runtime_set_autosuspend_delay(&clientp->dev,
0858 TSL2583_POWER_OFF_DELAY_MS);
0859 pm_runtime_use_autosuspend(&clientp->dev);
0860
0861 ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
0862 if (ret) {
0863 dev_err(&clientp->dev, "%s: iio registration failed\n",
0864 __func__);
0865 return ret;
0866 }
0867
0868
0869 tsl2583_defaults(chip);
0870
0871 dev_info(&clientp->dev, "Light sensor found.\n");
0872
0873 return 0;
0874 }
0875
0876 static int tsl2583_remove(struct i2c_client *client)
0877 {
0878 struct iio_dev *indio_dev = i2c_get_clientdata(client);
0879 struct tsl2583_chip *chip = iio_priv(indio_dev);
0880
0881 iio_device_unregister(indio_dev);
0882
0883 pm_runtime_disable(&client->dev);
0884 pm_runtime_set_suspended(&client->dev);
0885
0886 tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
0887
0888 return 0;
0889 }
0890
0891 static int tsl2583_suspend(struct device *dev)
0892 {
0893 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0894 struct tsl2583_chip *chip = iio_priv(indio_dev);
0895 int ret;
0896
0897 mutex_lock(&chip->als_mutex);
0898
0899 ret = tsl2583_set_power_state(chip, TSL2583_CNTL_PWR_OFF);
0900
0901 mutex_unlock(&chip->als_mutex);
0902
0903 return ret;
0904 }
0905
0906 static int tsl2583_resume(struct device *dev)
0907 {
0908 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0909 struct tsl2583_chip *chip = iio_priv(indio_dev);
0910 int ret;
0911
0912 mutex_lock(&chip->als_mutex);
0913
0914 ret = tsl2583_chip_init_and_power_on(indio_dev);
0915
0916 mutex_unlock(&chip->als_mutex);
0917
0918 return ret;
0919 }
0920
0921 static DEFINE_RUNTIME_DEV_PM_OPS(tsl2583_pm_ops, tsl2583_suspend,
0922 tsl2583_resume, NULL);
0923
0924 static const struct i2c_device_id tsl2583_idtable[] = {
0925 { "tsl2580", 0 },
0926 { "tsl2581", 1 },
0927 { "tsl2583", 2 },
0928 {}
0929 };
0930 MODULE_DEVICE_TABLE(i2c, tsl2583_idtable);
0931
0932 static const struct of_device_id tsl2583_of_match[] = {
0933 { .compatible = "amstaos,tsl2580", },
0934 { .compatible = "amstaos,tsl2581", },
0935 { .compatible = "amstaos,tsl2583", },
0936 { },
0937 };
0938 MODULE_DEVICE_TABLE(of, tsl2583_of_match);
0939
0940
0941 static struct i2c_driver tsl2583_driver = {
0942 .driver = {
0943 .name = "tsl2583",
0944 .pm = pm_ptr(&tsl2583_pm_ops),
0945 .of_match_table = tsl2583_of_match,
0946 },
0947 .id_table = tsl2583_idtable,
0948 .probe = tsl2583_probe,
0949 .remove = tsl2583_remove,
0950 };
0951 module_i2c_driver(tsl2583_driver);
0952
0953 MODULE_AUTHOR("J. August Brenner <jbrenner@taosinc.com>");
0954 MODULE_AUTHOR("Brian Masney <masneyb@onstation.org>");
0955 MODULE_DESCRIPTION("TAOS tsl2583 ambient light sensor driver");
0956 MODULE_LICENSE("GPL");