0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/atomic.h>
0011 #include <linux/fs.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/iio/events.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/module.h>
0017 #include <linux/mutex.h>
0018 #include <linux/mfd/core.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/slab.h>
0021 #include <linux/uaccess.h>
0022
0023 #include <linux/mfd/lm3533.h>
0024
0025
0026 #define LM3533_ALS_RESISTOR_MIN 1
0027 #define LM3533_ALS_RESISTOR_MAX 127
0028 #define LM3533_ALS_CHANNEL_CURRENT_MAX 2
0029 #define LM3533_ALS_THRESH_MAX 3
0030 #define LM3533_ALS_ZONE_MAX 4
0031
0032 #define LM3533_REG_ALS_RESISTOR_SELECT 0x30
0033 #define LM3533_REG_ALS_CONF 0x31
0034 #define LM3533_REG_ALS_ZONE_INFO 0x34
0035 #define LM3533_REG_ALS_READ_ADC_RAW 0x37
0036 #define LM3533_REG_ALS_READ_ADC_AVERAGE 0x38
0037 #define LM3533_REG_ALS_BOUNDARY_BASE 0x50
0038 #define LM3533_REG_ALS_TARGET_BASE 0x60
0039
0040 #define LM3533_ALS_ENABLE_MASK 0x01
0041 #define LM3533_ALS_INPUT_MODE_MASK 0x02
0042 #define LM3533_ALS_INT_ENABLE_MASK 0x01
0043
0044 #define LM3533_ALS_ZONE_SHIFT 2
0045 #define LM3533_ALS_ZONE_MASK 0x1c
0046
0047 #define LM3533_ALS_FLAG_INT_ENABLED 1
0048
0049
0050 struct lm3533_als {
0051 struct lm3533 *lm3533;
0052 struct platform_device *pdev;
0053
0054 unsigned long flags;
0055 int irq;
0056
0057 atomic_t zone;
0058 struct mutex thresh_mutex;
0059 };
0060
0061
0062 static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
0063 int *adc)
0064 {
0065 struct lm3533_als *als = iio_priv(indio_dev);
0066 u8 reg;
0067 u8 val;
0068 int ret;
0069
0070 if (average)
0071 reg = LM3533_REG_ALS_READ_ADC_AVERAGE;
0072 else
0073 reg = LM3533_REG_ALS_READ_ADC_RAW;
0074
0075 ret = lm3533_read(als->lm3533, reg, &val);
0076 if (ret) {
0077 dev_err(&indio_dev->dev, "failed to read adc\n");
0078 return ret;
0079 }
0080
0081 *adc = val;
0082
0083 return 0;
0084 }
0085
0086 static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
0087 {
0088 struct lm3533_als *als = iio_priv(indio_dev);
0089 u8 val;
0090 int ret;
0091
0092 ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
0093 if (ret) {
0094 dev_err(&indio_dev->dev, "failed to read zone\n");
0095 return ret;
0096 }
0097
0098 val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT;
0099 *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX);
0100
0101 return 0;
0102 }
0103
0104 static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
0105 {
0106 struct lm3533_als *als = iio_priv(indio_dev);
0107 int ret;
0108
0109 if (test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags)) {
0110 *zone = atomic_read(&als->zone);
0111 } else {
0112 ret = _lm3533_als_get_zone(indio_dev, zone);
0113 if (ret)
0114 return ret;
0115 }
0116
0117 return 0;
0118 }
0119
0120
0121
0122
0123
0124 static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone)
0125 {
0126 return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone;
0127 }
0128
0129 static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
0130 unsigned zone, u8 *val)
0131 {
0132 struct lm3533_als *als = iio_priv(indio_dev);
0133 u8 reg;
0134 int ret;
0135
0136 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
0137 return -EINVAL;
0138
0139 if (zone > LM3533_ALS_ZONE_MAX)
0140 return -EINVAL;
0141
0142 reg = lm3533_als_get_target_reg(channel, zone);
0143 ret = lm3533_read(als->lm3533, reg, val);
0144 if (ret)
0145 dev_err(&indio_dev->dev, "failed to get target current\n");
0146
0147 return ret;
0148 }
0149
0150 static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
0151 unsigned zone, u8 val)
0152 {
0153 struct lm3533_als *als = iio_priv(indio_dev);
0154 u8 reg;
0155 int ret;
0156
0157 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX)
0158 return -EINVAL;
0159
0160 if (zone > LM3533_ALS_ZONE_MAX)
0161 return -EINVAL;
0162
0163 reg = lm3533_als_get_target_reg(channel, zone);
0164 ret = lm3533_write(als->lm3533, reg, val);
0165 if (ret)
0166 dev_err(&indio_dev->dev, "failed to set target current\n");
0167
0168 return ret;
0169 }
0170
0171 static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel,
0172 int *val)
0173 {
0174 u8 zone;
0175 u8 target;
0176 int ret;
0177
0178 ret = lm3533_als_get_zone(indio_dev, &zone);
0179 if (ret)
0180 return ret;
0181
0182 ret = lm3533_als_get_target(indio_dev, channel, zone, &target);
0183 if (ret)
0184 return ret;
0185
0186 *val = target;
0187
0188 return 0;
0189 }
0190
0191 static int lm3533_als_read_raw(struct iio_dev *indio_dev,
0192 struct iio_chan_spec const *chan,
0193 int *val, int *val2, long mask)
0194 {
0195 int ret;
0196
0197 switch (mask) {
0198 case IIO_CHAN_INFO_RAW:
0199 switch (chan->type) {
0200 case IIO_LIGHT:
0201 ret = lm3533_als_get_adc(indio_dev, false, val);
0202 break;
0203 case IIO_CURRENT:
0204 ret = lm3533_als_get_current(indio_dev, chan->channel,
0205 val);
0206 break;
0207 default:
0208 return -EINVAL;
0209 }
0210 break;
0211 case IIO_CHAN_INFO_AVERAGE_RAW:
0212 ret = lm3533_als_get_adc(indio_dev, true, val);
0213 break;
0214 default:
0215 return -EINVAL;
0216 }
0217
0218 if (ret)
0219 return ret;
0220
0221 return IIO_VAL_INT;
0222 }
0223
0224 #define CHANNEL_CURRENT(_channel) \
0225 { \
0226 .type = IIO_CURRENT, \
0227 .channel = _channel, \
0228 .indexed = true, \
0229 .output = true, \
0230 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0231 }
0232
0233 static const struct iio_chan_spec lm3533_als_channels[] = {
0234 {
0235 .type = IIO_LIGHT,
0236 .channel = 0,
0237 .indexed = true,
0238 .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
0239 BIT(IIO_CHAN_INFO_RAW),
0240 },
0241 CHANNEL_CURRENT(0),
0242 CHANNEL_CURRENT(1),
0243 CHANNEL_CURRENT(2),
0244 };
0245
0246 static irqreturn_t lm3533_als_isr(int irq, void *dev_id)
0247 {
0248
0249 struct iio_dev *indio_dev = dev_id;
0250 struct lm3533_als *als = iio_priv(indio_dev);
0251 u8 zone;
0252 int ret;
0253
0254
0255 ret = _lm3533_als_get_zone(indio_dev, &zone);
0256 if (ret)
0257 goto out;
0258
0259 atomic_set(&als->zone, zone);
0260
0261 iio_push_event(indio_dev,
0262 IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
0263 0,
0264 IIO_EV_TYPE_THRESH,
0265 IIO_EV_DIR_EITHER),
0266 iio_get_time_ns(indio_dev));
0267 out:
0268 return IRQ_HANDLED;
0269 }
0270
0271 static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
0272 {
0273 struct lm3533_als *als = iio_priv(indio_dev);
0274 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
0275 u8 val;
0276 int ret;
0277
0278 if (enable)
0279 val = mask;
0280 else
0281 val = 0;
0282
0283 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask);
0284 if (ret) {
0285 dev_err(&indio_dev->dev, "failed to set int mode %d\n",
0286 enable);
0287 return ret;
0288 }
0289
0290 return 0;
0291 }
0292
0293 static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable)
0294 {
0295 struct lm3533_als *als = iio_priv(indio_dev);
0296 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
0297 u8 val;
0298 int ret;
0299
0300 ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
0301 if (ret) {
0302 dev_err(&indio_dev->dev, "failed to get int mode\n");
0303 return ret;
0304 }
0305
0306 *enable = !!(val & mask);
0307
0308 return 0;
0309 }
0310
0311 static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising)
0312 {
0313 u8 offset = !raising;
0314
0315 return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset;
0316 }
0317
0318 static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
0319 bool raising, u8 *val)
0320 {
0321 struct lm3533_als *als = iio_priv(indio_dev);
0322 u8 reg;
0323 int ret;
0324
0325 if (nr > LM3533_ALS_THRESH_MAX)
0326 return -EINVAL;
0327
0328 reg = lm3533_als_get_threshold_reg(nr, raising);
0329 ret = lm3533_read(als->lm3533, reg, val);
0330 if (ret)
0331 dev_err(&indio_dev->dev, "failed to get threshold\n");
0332
0333 return ret;
0334 }
0335
0336 static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
0337 bool raising, u8 val)
0338 {
0339 struct lm3533_als *als = iio_priv(indio_dev);
0340 u8 val2;
0341 u8 reg, reg2;
0342 int ret;
0343
0344 if (nr > LM3533_ALS_THRESH_MAX)
0345 return -EINVAL;
0346
0347 reg = lm3533_als_get_threshold_reg(nr, raising);
0348 reg2 = lm3533_als_get_threshold_reg(nr, !raising);
0349
0350 mutex_lock(&als->thresh_mutex);
0351 ret = lm3533_read(als->lm3533, reg2, &val2);
0352 if (ret) {
0353 dev_err(&indio_dev->dev, "failed to get threshold\n");
0354 goto out;
0355 }
0356
0357
0358
0359
0360
0361 if ((raising && (val < val2)) || (!raising && (val > val2))) {
0362 ret = -EINVAL;
0363 goto out;
0364 }
0365
0366 ret = lm3533_write(als->lm3533, reg, val);
0367 if (ret) {
0368 dev_err(&indio_dev->dev, "failed to set threshold\n");
0369 goto out;
0370 }
0371 out:
0372 mutex_unlock(&als->thresh_mutex);
0373
0374 return ret;
0375 }
0376
0377 static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr,
0378 u8 *val)
0379 {
0380 struct lm3533_als *als = iio_priv(indio_dev);
0381 u8 falling;
0382 u8 raising;
0383 int ret;
0384
0385 if (nr > LM3533_ALS_THRESH_MAX)
0386 return -EINVAL;
0387
0388 mutex_lock(&als->thresh_mutex);
0389 ret = lm3533_als_get_threshold(indio_dev, nr, false, &falling);
0390 if (ret)
0391 goto out;
0392 ret = lm3533_als_get_threshold(indio_dev, nr, true, &raising);
0393 if (ret)
0394 goto out;
0395
0396 *val = raising - falling;
0397 out:
0398 mutex_unlock(&als->thresh_mutex);
0399
0400 return ret;
0401 }
0402
0403 static ssize_t show_thresh_either_en(struct device *dev,
0404 struct device_attribute *attr,
0405 char *buf)
0406 {
0407 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0408 struct lm3533_als *als = iio_priv(indio_dev);
0409 int enable;
0410 int ret;
0411
0412 if (als->irq) {
0413 ret = lm3533_als_get_int_mode(indio_dev, &enable);
0414 if (ret)
0415 return ret;
0416 } else {
0417 enable = 0;
0418 }
0419
0420 return sysfs_emit(buf, "%u\n", enable);
0421 }
0422
0423 static ssize_t store_thresh_either_en(struct device *dev,
0424 struct device_attribute *attr,
0425 const char *buf, size_t len)
0426 {
0427 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0428 struct lm3533_als *als = iio_priv(indio_dev);
0429 unsigned long enable;
0430 bool int_enabled;
0431 u8 zone;
0432 int ret;
0433
0434 if (!als->irq)
0435 return -EBUSY;
0436
0437 if (kstrtoul(buf, 0, &enable))
0438 return -EINVAL;
0439
0440 int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
0441
0442 if (enable && !int_enabled) {
0443 ret = lm3533_als_get_zone(indio_dev, &zone);
0444 if (ret)
0445 return ret;
0446
0447 atomic_set(&als->zone, zone);
0448
0449 set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
0450 }
0451
0452 ret = lm3533_als_set_int_mode(indio_dev, enable);
0453 if (ret) {
0454 if (!int_enabled)
0455 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
0456
0457 return ret;
0458 }
0459
0460 if (!enable)
0461 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags);
0462
0463 return len;
0464 }
0465
0466 static ssize_t show_zone(struct device *dev,
0467 struct device_attribute *attr, char *buf)
0468 {
0469 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0470 u8 zone;
0471 int ret;
0472
0473 ret = lm3533_als_get_zone(indio_dev, &zone);
0474 if (ret)
0475 return ret;
0476
0477 return sysfs_emit(buf, "%u\n", zone);
0478 }
0479
0480 enum lm3533_als_attribute_type {
0481 LM3533_ATTR_TYPE_HYSTERESIS,
0482 LM3533_ATTR_TYPE_TARGET,
0483 LM3533_ATTR_TYPE_THRESH_FALLING,
0484 LM3533_ATTR_TYPE_THRESH_RAISING,
0485 };
0486
0487 struct lm3533_als_attribute {
0488 struct device_attribute dev_attr;
0489 enum lm3533_als_attribute_type type;
0490 u8 val1;
0491 u8 val2;
0492 };
0493
0494 static inline struct lm3533_als_attribute *
0495 to_lm3533_als_attr(struct device_attribute *attr)
0496 {
0497 return container_of(attr, struct lm3533_als_attribute, dev_attr);
0498 }
0499
0500 static ssize_t show_als_attr(struct device *dev,
0501 struct device_attribute *attr,
0502 char *buf)
0503 {
0504 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0505 struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
0506 u8 val;
0507 int ret;
0508
0509 switch (als_attr->type) {
0510 case LM3533_ATTR_TYPE_HYSTERESIS:
0511 ret = lm3533_als_get_hysteresis(indio_dev, als_attr->val1,
0512 &val);
0513 break;
0514 case LM3533_ATTR_TYPE_TARGET:
0515 ret = lm3533_als_get_target(indio_dev, als_attr->val1,
0516 als_attr->val2, &val);
0517 break;
0518 case LM3533_ATTR_TYPE_THRESH_FALLING:
0519 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
0520 false, &val);
0521 break;
0522 case LM3533_ATTR_TYPE_THRESH_RAISING:
0523 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1,
0524 true, &val);
0525 break;
0526 default:
0527 ret = -ENXIO;
0528 }
0529
0530 if (ret)
0531 return ret;
0532
0533 return sysfs_emit(buf, "%u\n", val);
0534 }
0535
0536 static ssize_t store_als_attr(struct device *dev,
0537 struct device_attribute *attr,
0538 const char *buf, size_t len)
0539 {
0540 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0541 struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
0542 u8 val;
0543 int ret;
0544
0545 if (kstrtou8(buf, 0, &val))
0546 return -EINVAL;
0547
0548 switch (als_attr->type) {
0549 case LM3533_ATTR_TYPE_TARGET:
0550 ret = lm3533_als_set_target(indio_dev, als_attr->val1,
0551 als_attr->val2, val);
0552 break;
0553 case LM3533_ATTR_TYPE_THRESH_FALLING:
0554 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
0555 false, val);
0556 break;
0557 case LM3533_ATTR_TYPE_THRESH_RAISING:
0558 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1,
0559 true, val);
0560 break;
0561 default:
0562 ret = -ENXIO;
0563 }
0564
0565 if (ret)
0566 return ret;
0567
0568 return len;
0569 }
0570
0571 #define ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \
0572 { .dev_attr = __ATTR(_name, _mode, _show, _store), \
0573 .type = _type, \
0574 .val1 = _val1, \
0575 .val2 = _val2 }
0576
0577 #define LM3533_ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \
0578 struct lm3533_als_attribute lm3533_als_attr_##_name = \
0579 ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2)
0580
0581 #define ALS_TARGET_ATTR_RW(_channel, _zone) \
0582 LM3533_ALS_ATTR(out_current##_channel##_current##_zone##_raw, \
0583 S_IRUGO | S_IWUSR, \
0584 show_als_attr, store_als_attr, \
0585 LM3533_ATTR_TYPE_TARGET, _channel, _zone)
0586
0587
0588
0589
0590
0591 static ALS_TARGET_ATTR_RW(0, 0);
0592 static ALS_TARGET_ATTR_RW(0, 1);
0593 static ALS_TARGET_ATTR_RW(0, 2);
0594 static ALS_TARGET_ATTR_RW(0, 3);
0595 static ALS_TARGET_ATTR_RW(0, 4);
0596
0597 static ALS_TARGET_ATTR_RW(1, 0);
0598 static ALS_TARGET_ATTR_RW(1, 1);
0599 static ALS_TARGET_ATTR_RW(1, 2);
0600 static ALS_TARGET_ATTR_RW(1, 3);
0601 static ALS_TARGET_ATTR_RW(1, 4);
0602
0603 static ALS_TARGET_ATTR_RW(2, 0);
0604 static ALS_TARGET_ATTR_RW(2, 1);
0605 static ALS_TARGET_ATTR_RW(2, 2);
0606 static ALS_TARGET_ATTR_RW(2, 3);
0607 static ALS_TARGET_ATTR_RW(2, 4);
0608
0609 #define ALS_THRESH_FALLING_ATTR_RW(_nr) \
0610 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_falling_value, \
0611 S_IRUGO | S_IWUSR, \
0612 show_als_attr, store_als_attr, \
0613 LM3533_ATTR_TYPE_THRESH_FALLING, _nr, 0)
0614
0615 #define ALS_THRESH_RAISING_ATTR_RW(_nr) \
0616 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_raising_value, \
0617 S_IRUGO | S_IWUSR, \
0618 show_als_attr, store_als_attr, \
0619 LM3533_ATTR_TYPE_THRESH_RAISING, _nr, 0)
0620
0621
0622
0623
0624
0625
0626 static ALS_THRESH_FALLING_ATTR_RW(0);
0627 static ALS_THRESH_FALLING_ATTR_RW(1);
0628 static ALS_THRESH_FALLING_ATTR_RW(2);
0629 static ALS_THRESH_FALLING_ATTR_RW(3);
0630
0631 static ALS_THRESH_RAISING_ATTR_RW(0);
0632 static ALS_THRESH_RAISING_ATTR_RW(1);
0633 static ALS_THRESH_RAISING_ATTR_RW(2);
0634 static ALS_THRESH_RAISING_ATTR_RW(3);
0635
0636 #define ALS_HYSTERESIS_ATTR_RO(_nr) \
0637 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_hysteresis, \
0638 S_IRUGO, show_als_attr, NULL, \
0639 LM3533_ATTR_TYPE_HYSTERESIS, _nr, 0)
0640
0641
0642
0643
0644
0645
0646
0647
0648 static ALS_HYSTERESIS_ATTR_RO(0);
0649 static ALS_HYSTERESIS_ATTR_RO(1);
0650 static ALS_HYSTERESIS_ATTR_RO(2);
0651 static ALS_HYSTERESIS_ATTR_RO(3);
0652
0653 #define ILLUMINANCE_ATTR_RO(_name) \
0654 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL)
0655 #define ILLUMINANCE_ATTR_RW(_name) \
0656 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \
0657 show_##_name, store_##_name)
0658
0659
0660
0661
0662
0663 static ILLUMINANCE_ATTR_RW(thresh_either_en);
0664
0665
0666
0667
0668
0669
0670 static ILLUMINANCE_ATTR_RO(zone);
0671
0672 static struct attribute *lm3533_als_event_attributes[] = {
0673 &dev_attr_in_illuminance0_thresh_either_en.attr,
0674 &lm3533_als_attr_in_illuminance0_thresh0_falling_value.dev_attr.attr,
0675 &lm3533_als_attr_in_illuminance0_thresh0_hysteresis.dev_attr.attr,
0676 &lm3533_als_attr_in_illuminance0_thresh0_raising_value.dev_attr.attr,
0677 &lm3533_als_attr_in_illuminance0_thresh1_falling_value.dev_attr.attr,
0678 &lm3533_als_attr_in_illuminance0_thresh1_hysteresis.dev_attr.attr,
0679 &lm3533_als_attr_in_illuminance0_thresh1_raising_value.dev_attr.attr,
0680 &lm3533_als_attr_in_illuminance0_thresh2_falling_value.dev_attr.attr,
0681 &lm3533_als_attr_in_illuminance0_thresh2_hysteresis.dev_attr.attr,
0682 &lm3533_als_attr_in_illuminance0_thresh2_raising_value.dev_attr.attr,
0683 &lm3533_als_attr_in_illuminance0_thresh3_falling_value.dev_attr.attr,
0684 &lm3533_als_attr_in_illuminance0_thresh3_hysteresis.dev_attr.attr,
0685 &lm3533_als_attr_in_illuminance0_thresh3_raising_value.dev_attr.attr,
0686 NULL
0687 };
0688
0689 static const struct attribute_group lm3533_als_event_attribute_group = {
0690 .attrs = lm3533_als_event_attributes
0691 };
0692
0693 static struct attribute *lm3533_als_attributes[] = {
0694 &dev_attr_in_illuminance0_zone.attr,
0695 &lm3533_als_attr_out_current0_current0_raw.dev_attr.attr,
0696 &lm3533_als_attr_out_current0_current1_raw.dev_attr.attr,
0697 &lm3533_als_attr_out_current0_current2_raw.dev_attr.attr,
0698 &lm3533_als_attr_out_current0_current3_raw.dev_attr.attr,
0699 &lm3533_als_attr_out_current0_current4_raw.dev_attr.attr,
0700 &lm3533_als_attr_out_current1_current0_raw.dev_attr.attr,
0701 &lm3533_als_attr_out_current1_current1_raw.dev_attr.attr,
0702 &lm3533_als_attr_out_current1_current2_raw.dev_attr.attr,
0703 &lm3533_als_attr_out_current1_current3_raw.dev_attr.attr,
0704 &lm3533_als_attr_out_current1_current4_raw.dev_attr.attr,
0705 &lm3533_als_attr_out_current2_current0_raw.dev_attr.attr,
0706 &lm3533_als_attr_out_current2_current1_raw.dev_attr.attr,
0707 &lm3533_als_attr_out_current2_current2_raw.dev_attr.attr,
0708 &lm3533_als_attr_out_current2_current3_raw.dev_attr.attr,
0709 &lm3533_als_attr_out_current2_current4_raw.dev_attr.attr,
0710 NULL
0711 };
0712
0713 static const struct attribute_group lm3533_als_attribute_group = {
0714 .attrs = lm3533_als_attributes
0715 };
0716
0717 static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode)
0718 {
0719 u8 mask = LM3533_ALS_INPUT_MODE_MASK;
0720 u8 val;
0721 int ret;
0722
0723 if (pwm_mode)
0724 val = mask;
0725 else
0726 val = 0;
0727
0728 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask);
0729 if (ret) {
0730 dev_err(&als->pdev->dev, "failed to set input mode %d\n",
0731 pwm_mode);
0732 return ret;
0733 }
0734
0735 return 0;
0736 }
0737
0738 static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
0739 {
0740 int ret;
0741
0742 if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) {
0743 dev_err(&als->pdev->dev, "invalid resistor value\n");
0744 return -EINVAL;
0745 }
0746
0747 ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
0748 if (ret) {
0749 dev_err(&als->pdev->dev, "failed to set resistor\n");
0750 return ret;
0751 }
0752
0753 return 0;
0754 }
0755
0756 static int lm3533_als_setup(struct lm3533_als *als,
0757 struct lm3533_als_platform_data *pdata)
0758 {
0759 int ret;
0760
0761 ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
0762 if (ret)
0763 return ret;
0764
0765
0766 if (!pdata->pwm_mode) {
0767 ret = lm3533_als_set_resistor(als, pdata->r_select);
0768 if (ret)
0769 return ret;
0770 }
0771
0772 return 0;
0773 }
0774
0775 static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
0776 {
0777 u8 mask = LM3533_ALS_INT_ENABLE_MASK;
0778 int ret;
0779
0780
0781 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask);
0782 if (ret) {
0783 dev_err(&als->pdev->dev, "failed to disable interrupts\n");
0784 return ret;
0785 }
0786
0787 ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr,
0788 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0789 dev_name(&als->pdev->dev), dev);
0790 if (ret) {
0791 dev_err(&als->pdev->dev, "failed to request irq %d\n",
0792 als->irq);
0793 return ret;
0794 }
0795
0796 return 0;
0797 }
0798
0799 static int lm3533_als_enable(struct lm3533_als *als)
0800 {
0801 u8 mask = LM3533_ALS_ENABLE_MASK;
0802 int ret;
0803
0804 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask);
0805 if (ret)
0806 dev_err(&als->pdev->dev, "failed to enable ALS\n");
0807
0808 return ret;
0809 }
0810
0811 static int lm3533_als_disable(struct lm3533_als *als)
0812 {
0813 u8 mask = LM3533_ALS_ENABLE_MASK;
0814 int ret;
0815
0816 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask);
0817 if (ret)
0818 dev_err(&als->pdev->dev, "failed to disable ALS\n");
0819
0820 return ret;
0821 }
0822
0823 static const struct iio_info lm3533_als_info = {
0824 .attrs = &lm3533_als_attribute_group,
0825 .event_attrs = &lm3533_als_event_attribute_group,
0826 .read_raw = &lm3533_als_read_raw,
0827 };
0828
0829 static int lm3533_als_probe(struct platform_device *pdev)
0830 {
0831 struct lm3533 *lm3533;
0832 struct lm3533_als_platform_data *pdata;
0833 struct lm3533_als *als;
0834 struct iio_dev *indio_dev;
0835 int ret;
0836
0837 lm3533 = dev_get_drvdata(pdev->dev.parent);
0838 if (!lm3533)
0839 return -EINVAL;
0840
0841 pdata = pdev->dev.platform_data;
0842 if (!pdata) {
0843 dev_err(&pdev->dev, "no platform data\n");
0844 return -EINVAL;
0845 }
0846
0847 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
0848 if (!indio_dev)
0849 return -ENOMEM;
0850
0851 indio_dev->info = &lm3533_als_info;
0852 indio_dev->channels = lm3533_als_channels;
0853 indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
0854 indio_dev->name = dev_name(&pdev->dev);
0855 iio_device_set_parent(indio_dev, pdev->dev.parent);
0856 indio_dev->modes = INDIO_DIRECT_MODE;
0857
0858 als = iio_priv(indio_dev);
0859 als->lm3533 = lm3533;
0860 als->pdev = pdev;
0861 als->irq = lm3533->irq;
0862 atomic_set(&als->zone, 0);
0863 mutex_init(&als->thresh_mutex);
0864
0865 platform_set_drvdata(pdev, indio_dev);
0866
0867 if (als->irq) {
0868 ret = lm3533_als_setup_irq(als, indio_dev);
0869 if (ret)
0870 return ret;
0871 }
0872
0873 ret = lm3533_als_setup(als, pdata);
0874 if (ret)
0875 goto err_free_irq;
0876
0877 ret = lm3533_als_enable(als);
0878 if (ret)
0879 goto err_free_irq;
0880
0881 ret = iio_device_register(indio_dev);
0882 if (ret) {
0883 dev_err(&pdev->dev, "failed to register ALS\n");
0884 goto err_disable;
0885 }
0886
0887 return 0;
0888
0889 err_disable:
0890 lm3533_als_disable(als);
0891 err_free_irq:
0892 if (als->irq)
0893 free_irq(als->irq, indio_dev);
0894
0895 return ret;
0896 }
0897
0898 static int lm3533_als_remove(struct platform_device *pdev)
0899 {
0900 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
0901 struct lm3533_als *als = iio_priv(indio_dev);
0902
0903 lm3533_als_set_int_mode(indio_dev, false);
0904 iio_device_unregister(indio_dev);
0905 lm3533_als_disable(als);
0906 if (als->irq)
0907 free_irq(als->irq, indio_dev);
0908
0909 return 0;
0910 }
0911
0912 static struct platform_driver lm3533_als_driver = {
0913 .driver = {
0914 .name = "lm3533-als",
0915 },
0916 .probe = lm3533_als_probe,
0917 .remove = lm3533_als_remove,
0918 };
0919 module_platform_driver(lm3533_als_driver);
0920
0921 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
0922 MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver");
0923 MODULE_LICENSE("GPL");
0924 MODULE_ALIAS("platform:lm3533-als");