Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * lm3533-als.c -- LM3533 Ambient Light Sensor driver
0004  *
0005  * Copyright (C) 2011-2012 Texas Instruments
0006  *
0007  * Author: Johan Hovold <jhovold@gmail.com>
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  * channel  output channel 0..2
0122  * zone     zone 0..4
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     /* Clear interrupt by reading the ALS zone register. */
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      * This device does not allow negative hysteresis (in fact, it uses
0358      * whichever value is smaller as the lower bound) so we need to make
0359      * sure that thresh_falling <= thresh_raising.
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  * ALS output current values (ALS mapper targets)
0588  *
0589  * out_current[0-2]_current[0-4]_raw        0-255
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  * ALS Zone thresholds (boundaries)
0622  *
0623  * in_illuminance0_thresh[0-3]_falling_value    0-255
0624  * in_illuminance0_thresh[0-3]_raising_value    0-255
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  * ALS Zone threshold hysteresis
0642  *
0643  * threshY_hysteresis = threshY_raising - threshY_falling
0644  *
0645  * in_illuminance0_thresh[0-3]_hysteresis   0-255
0646  * in_illuminance0_thresh[0-3]_hysteresis   0-255
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  * ALS Zone threshold-event enable
0660  *
0661  * in_illuminance0_thresh_either_en     0,1
0662  */
0663 static ILLUMINANCE_ATTR_RW(thresh_either_en);
0664 
0665 /*
0666  * ALS Current Zone
0667  *
0668  * in_illuminance0_zone     0-4
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; /* pwm input */
0725     else
0726         val = 0;    /* analog input */
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     /* ALS input is always high impedance in PWM-mode. */
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     /* Make sure interrupts are disabled. */
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");