lm3533-als.c (22045B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * lm3533-als.c -- LM3533 Ambient Light Sensor driver 4 * 5 * Copyright (C) 2011-2012 Texas Instruments 6 * 7 * Author: Johan Hovold <jhovold@gmail.com> 8 */ 9 10#include <linux/atomic.h> 11#include <linux/fs.h> 12#include <linux/interrupt.h> 13#include <linux/io.h> 14#include <linux/iio/events.h> 15#include <linux/iio/iio.h> 16#include <linux/module.h> 17#include <linux/mutex.h> 18#include <linux/mfd/core.h> 19#include <linux/platform_device.h> 20#include <linux/slab.h> 21#include <linux/uaccess.h> 22 23#include <linux/mfd/lm3533.h> 24 25 26#define LM3533_ALS_RESISTOR_MIN 1 27#define LM3533_ALS_RESISTOR_MAX 127 28#define LM3533_ALS_CHANNEL_CURRENT_MAX 2 29#define LM3533_ALS_THRESH_MAX 3 30#define LM3533_ALS_ZONE_MAX 4 31 32#define LM3533_REG_ALS_RESISTOR_SELECT 0x30 33#define LM3533_REG_ALS_CONF 0x31 34#define LM3533_REG_ALS_ZONE_INFO 0x34 35#define LM3533_REG_ALS_READ_ADC_RAW 0x37 36#define LM3533_REG_ALS_READ_ADC_AVERAGE 0x38 37#define LM3533_REG_ALS_BOUNDARY_BASE 0x50 38#define LM3533_REG_ALS_TARGET_BASE 0x60 39 40#define LM3533_ALS_ENABLE_MASK 0x01 41#define LM3533_ALS_INPUT_MODE_MASK 0x02 42#define LM3533_ALS_INT_ENABLE_MASK 0x01 43 44#define LM3533_ALS_ZONE_SHIFT 2 45#define LM3533_ALS_ZONE_MASK 0x1c 46 47#define LM3533_ALS_FLAG_INT_ENABLED 1 48 49 50struct lm3533_als { 51 struct lm3533 *lm3533; 52 struct platform_device *pdev; 53 54 unsigned long flags; 55 int irq; 56 57 atomic_t zone; 58 struct mutex thresh_mutex; 59}; 60 61 62static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average, 63 int *adc) 64{ 65 struct lm3533_als *als = iio_priv(indio_dev); 66 u8 reg; 67 u8 val; 68 int ret; 69 70 if (average) 71 reg = LM3533_REG_ALS_READ_ADC_AVERAGE; 72 else 73 reg = LM3533_REG_ALS_READ_ADC_RAW; 74 75 ret = lm3533_read(als->lm3533, reg, &val); 76 if (ret) { 77 dev_err(&indio_dev->dev, "failed to read adc\n"); 78 return ret; 79 } 80 81 *adc = val; 82 83 return 0; 84} 85 86static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone) 87{ 88 struct lm3533_als *als = iio_priv(indio_dev); 89 u8 val; 90 int ret; 91 92 ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); 93 if (ret) { 94 dev_err(&indio_dev->dev, "failed to read zone\n"); 95 return ret; 96 } 97 98 val = (val & LM3533_ALS_ZONE_MASK) >> LM3533_ALS_ZONE_SHIFT; 99 *zone = min_t(u8, val, LM3533_ALS_ZONE_MAX); 100 101 return 0; 102} 103 104static int lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone) 105{ 106 struct lm3533_als *als = iio_priv(indio_dev); 107 int ret; 108 109 if (test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags)) { 110 *zone = atomic_read(&als->zone); 111 } else { 112 ret = _lm3533_als_get_zone(indio_dev, zone); 113 if (ret) 114 return ret; 115 } 116 117 return 0; 118} 119 120/* 121 * channel output channel 0..2 122 * zone zone 0..4 123 */ 124static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone) 125{ 126 return LM3533_REG_ALS_TARGET_BASE + 5 * channel + zone; 127} 128 129static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel, 130 unsigned zone, u8 *val) 131{ 132 struct lm3533_als *als = iio_priv(indio_dev); 133 u8 reg; 134 int ret; 135 136 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX) 137 return -EINVAL; 138 139 if (zone > LM3533_ALS_ZONE_MAX) 140 return -EINVAL; 141 142 reg = lm3533_als_get_target_reg(channel, zone); 143 ret = lm3533_read(als->lm3533, reg, val); 144 if (ret) 145 dev_err(&indio_dev->dev, "failed to get target current\n"); 146 147 return ret; 148} 149 150static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel, 151 unsigned zone, u8 val) 152{ 153 struct lm3533_als *als = iio_priv(indio_dev); 154 u8 reg; 155 int ret; 156 157 if (channel > LM3533_ALS_CHANNEL_CURRENT_MAX) 158 return -EINVAL; 159 160 if (zone > LM3533_ALS_ZONE_MAX) 161 return -EINVAL; 162 163 reg = lm3533_als_get_target_reg(channel, zone); 164 ret = lm3533_write(als->lm3533, reg, val); 165 if (ret) 166 dev_err(&indio_dev->dev, "failed to set target current\n"); 167 168 return ret; 169} 170 171static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel, 172 int *val) 173{ 174 u8 zone; 175 u8 target; 176 int ret; 177 178 ret = lm3533_als_get_zone(indio_dev, &zone); 179 if (ret) 180 return ret; 181 182 ret = lm3533_als_get_target(indio_dev, channel, zone, &target); 183 if (ret) 184 return ret; 185 186 *val = target; 187 188 return 0; 189} 190 191static int lm3533_als_read_raw(struct iio_dev *indio_dev, 192 struct iio_chan_spec const *chan, 193 int *val, int *val2, long mask) 194{ 195 int ret; 196 197 switch (mask) { 198 case IIO_CHAN_INFO_RAW: 199 switch (chan->type) { 200 case IIO_LIGHT: 201 ret = lm3533_als_get_adc(indio_dev, false, val); 202 break; 203 case IIO_CURRENT: 204 ret = lm3533_als_get_current(indio_dev, chan->channel, 205 val); 206 break; 207 default: 208 return -EINVAL; 209 } 210 break; 211 case IIO_CHAN_INFO_AVERAGE_RAW: 212 ret = lm3533_als_get_adc(indio_dev, true, val); 213 break; 214 default: 215 return -EINVAL; 216 } 217 218 if (ret) 219 return ret; 220 221 return IIO_VAL_INT; 222} 223 224#define CHANNEL_CURRENT(_channel) \ 225 { \ 226 .type = IIO_CURRENT, \ 227 .channel = _channel, \ 228 .indexed = true, \ 229 .output = true, \ 230 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 231 } 232 233static const struct iio_chan_spec lm3533_als_channels[] = { 234 { 235 .type = IIO_LIGHT, 236 .channel = 0, 237 .indexed = true, 238 .info_mask_separate = BIT(IIO_CHAN_INFO_AVERAGE_RAW) | 239 BIT(IIO_CHAN_INFO_RAW), 240 }, 241 CHANNEL_CURRENT(0), 242 CHANNEL_CURRENT(1), 243 CHANNEL_CURRENT(2), 244}; 245 246static irqreturn_t lm3533_als_isr(int irq, void *dev_id) 247{ 248 249 struct iio_dev *indio_dev = dev_id; 250 struct lm3533_als *als = iio_priv(indio_dev); 251 u8 zone; 252 int ret; 253 254 /* Clear interrupt by reading the ALS zone register. */ 255 ret = _lm3533_als_get_zone(indio_dev, &zone); 256 if (ret) 257 goto out; 258 259 atomic_set(&als->zone, zone); 260 261 iio_push_event(indio_dev, 262 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 263 0, 264 IIO_EV_TYPE_THRESH, 265 IIO_EV_DIR_EITHER), 266 iio_get_time_ns(indio_dev)); 267out: 268 return IRQ_HANDLED; 269} 270 271static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable) 272{ 273 struct lm3533_als *als = iio_priv(indio_dev); 274 u8 mask = LM3533_ALS_INT_ENABLE_MASK; 275 u8 val; 276 int ret; 277 278 if (enable) 279 val = mask; 280 else 281 val = 0; 282 283 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask); 284 if (ret) { 285 dev_err(&indio_dev->dev, "failed to set int mode %d\n", 286 enable); 287 return ret; 288 } 289 290 return 0; 291} 292 293static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable) 294{ 295 struct lm3533_als *als = iio_priv(indio_dev); 296 u8 mask = LM3533_ALS_INT_ENABLE_MASK; 297 u8 val; 298 int ret; 299 300 ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val); 301 if (ret) { 302 dev_err(&indio_dev->dev, "failed to get int mode\n"); 303 return ret; 304 } 305 306 *enable = !!(val & mask); 307 308 return 0; 309} 310 311static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising) 312{ 313 u8 offset = !raising; 314 315 return LM3533_REG_ALS_BOUNDARY_BASE + 2 * nr + offset; 316} 317 318static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr, 319 bool raising, u8 *val) 320{ 321 struct lm3533_als *als = iio_priv(indio_dev); 322 u8 reg; 323 int ret; 324 325 if (nr > LM3533_ALS_THRESH_MAX) 326 return -EINVAL; 327 328 reg = lm3533_als_get_threshold_reg(nr, raising); 329 ret = lm3533_read(als->lm3533, reg, val); 330 if (ret) 331 dev_err(&indio_dev->dev, "failed to get threshold\n"); 332 333 return ret; 334} 335 336static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr, 337 bool raising, u8 val) 338{ 339 struct lm3533_als *als = iio_priv(indio_dev); 340 u8 val2; 341 u8 reg, reg2; 342 int ret; 343 344 if (nr > LM3533_ALS_THRESH_MAX) 345 return -EINVAL; 346 347 reg = lm3533_als_get_threshold_reg(nr, raising); 348 reg2 = lm3533_als_get_threshold_reg(nr, !raising); 349 350 mutex_lock(&als->thresh_mutex); 351 ret = lm3533_read(als->lm3533, reg2, &val2); 352 if (ret) { 353 dev_err(&indio_dev->dev, "failed to get threshold\n"); 354 goto out; 355 } 356 /* 357 * This device does not allow negative hysteresis (in fact, it uses 358 * whichever value is smaller as the lower bound) so we need to make 359 * sure that thresh_falling <= thresh_raising. 360 */ 361 if ((raising && (val < val2)) || (!raising && (val > val2))) { 362 ret = -EINVAL; 363 goto out; 364 } 365 366 ret = lm3533_write(als->lm3533, reg, val); 367 if (ret) { 368 dev_err(&indio_dev->dev, "failed to set threshold\n"); 369 goto out; 370 } 371out: 372 mutex_unlock(&als->thresh_mutex); 373 374 return ret; 375} 376 377static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr, 378 u8 *val) 379{ 380 struct lm3533_als *als = iio_priv(indio_dev); 381 u8 falling; 382 u8 raising; 383 int ret; 384 385 if (nr > LM3533_ALS_THRESH_MAX) 386 return -EINVAL; 387 388 mutex_lock(&als->thresh_mutex); 389 ret = lm3533_als_get_threshold(indio_dev, nr, false, &falling); 390 if (ret) 391 goto out; 392 ret = lm3533_als_get_threshold(indio_dev, nr, true, &raising); 393 if (ret) 394 goto out; 395 396 *val = raising - falling; 397out: 398 mutex_unlock(&als->thresh_mutex); 399 400 return ret; 401} 402 403static ssize_t show_thresh_either_en(struct device *dev, 404 struct device_attribute *attr, 405 char *buf) 406{ 407 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 408 struct lm3533_als *als = iio_priv(indio_dev); 409 int enable; 410 int ret; 411 412 if (als->irq) { 413 ret = lm3533_als_get_int_mode(indio_dev, &enable); 414 if (ret) 415 return ret; 416 } else { 417 enable = 0; 418 } 419 420 return sysfs_emit(buf, "%u\n", enable); 421} 422 423static ssize_t store_thresh_either_en(struct device *dev, 424 struct device_attribute *attr, 425 const char *buf, size_t len) 426{ 427 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 428 struct lm3533_als *als = iio_priv(indio_dev); 429 unsigned long enable; 430 bool int_enabled; 431 u8 zone; 432 int ret; 433 434 if (!als->irq) 435 return -EBUSY; 436 437 if (kstrtoul(buf, 0, &enable)) 438 return -EINVAL; 439 440 int_enabled = test_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); 441 442 if (enable && !int_enabled) { 443 ret = lm3533_als_get_zone(indio_dev, &zone); 444 if (ret) 445 return ret; 446 447 atomic_set(&als->zone, zone); 448 449 set_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); 450 } 451 452 ret = lm3533_als_set_int_mode(indio_dev, enable); 453 if (ret) { 454 if (!int_enabled) 455 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); 456 457 return ret; 458 } 459 460 if (!enable) 461 clear_bit(LM3533_ALS_FLAG_INT_ENABLED, &als->flags); 462 463 return len; 464} 465 466static ssize_t show_zone(struct device *dev, 467 struct device_attribute *attr, char *buf) 468{ 469 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 470 u8 zone; 471 int ret; 472 473 ret = lm3533_als_get_zone(indio_dev, &zone); 474 if (ret) 475 return ret; 476 477 return sysfs_emit(buf, "%u\n", zone); 478} 479 480enum lm3533_als_attribute_type { 481 LM3533_ATTR_TYPE_HYSTERESIS, 482 LM3533_ATTR_TYPE_TARGET, 483 LM3533_ATTR_TYPE_THRESH_FALLING, 484 LM3533_ATTR_TYPE_THRESH_RAISING, 485}; 486 487struct lm3533_als_attribute { 488 struct device_attribute dev_attr; 489 enum lm3533_als_attribute_type type; 490 u8 val1; 491 u8 val2; 492}; 493 494static inline struct lm3533_als_attribute * 495to_lm3533_als_attr(struct device_attribute *attr) 496{ 497 return container_of(attr, struct lm3533_als_attribute, dev_attr); 498} 499 500static ssize_t show_als_attr(struct device *dev, 501 struct device_attribute *attr, 502 char *buf) 503{ 504 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 505 struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr); 506 u8 val; 507 int ret; 508 509 switch (als_attr->type) { 510 case LM3533_ATTR_TYPE_HYSTERESIS: 511 ret = lm3533_als_get_hysteresis(indio_dev, als_attr->val1, 512 &val); 513 break; 514 case LM3533_ATTR_TYPE_TARGET: 515 ret = lm3533_als_get_target(indio_dev, als_attr->val1, 516 als_attr->val2, &val); 517 break; 518 case LM3533_ATTR_TYPE_THRESH_FALLING: 519 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1, 520 false, &val); 521 break; 522 case LM3533_ATTR_TYPE_THRESH_RAISING: 523 ret = lm3533_als_get_threshold(indio_dev, als_attr->val1, 524 true, &val); 525 break; 526 default: 527 ret = -ENXIO; 528 } 529 530 if (ret) 531 return ret; 532 533 return sysfs_emit(buf, "%u\n", val); 534} 535 536static ssize_t store_als_attr(struct device *dev, 537 struct device_attribute *attr, 538 const char *buf, size_t len) 539{ 540 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 541 struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr); 542 u8 val; 543 int ret; 544 545 if (kstrtou8(buf, 0, &val)) 546 return -EINVAL; 547 548 switch (als_attr->type) { 549 case LM3533_ATTR_TYPE_TARGET: 550 ret = lm3533_als_set_target(indio_dev, als_attr->val1, 551 als_attr->val2, val); 552 break; 553 case LM3533_ATTR_TYPE_THRESH_FALLING: 554 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1, 555 false, val); 556 break; 557 case LM3533_ATTR_TYPE_THRESH_RAISING: 558 ret = lm3533_als_set_threshold(indio_dev, als_attr->val1, 559 true, val); 560 break; 561 default: 562 ret = -ENXIO; 563 } 564 565 if (ret) 566 return ret; 567 568 return len; 569} 570 571#define ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \ 572 { .dev_attr = __ATTR(_name, _mode, _show, _store), \ 573 .type = _type, \ 574 .val1 = _val1, \ 575 .val2 = _val2 } 576 577#define LM3533_ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) \ 578 struct lm3533_als_attribute lm3533_als_attr_##_name = \ 579 ALS_ATTR(_name, _mode, _show, _store, _type, _val1, _val2) 580 581#define ALS_TARGET_ATTR_RW(_channel, _zone) \ 582 LM3533_ALS_ATTR(out_current##_channel##_current##_zone##_raw, \ 583 S_IRUGO | S_IWUSR, \ 584 show_als_attr, store_als_attr, \ 585 LM3533_ATTR_TYPE_TARGET, _channel, _zone) 586/* 587 * ALS output current values (ALS mapper targets) 588 * 589 * out_current[0-2]_current[0-4]_raw 0-255 590 */ 591static ALS_TARGET_ATTR_RW(0, 0); 592static ALS_TARGET_ATTR_RW(0, 1); 593static ALS_TARGET_ATTR_RW(0, 2); 594static ALS_TARGET_ATTR_RW(0, 3); 595static ALS_TARGET_ATTR_RW(0, 4); 596 597static ALS_TARGET_ATTR_RW(1, 0); 598static ALS_TARGET_ATTR_RW(1, 1); 599static ALS_TARGET_ATTR_RW(1, 2); 600static ALS_TARGET_ATTR_RW(1, 3); 601static ALS_TARGET_ATTR_RW(1, 4); 602 603static ALS_TARGET_ATTR_RW(2, 0); 604static ALS_TARGET_ATTR_RW(2, 1); 605static ALS_TARGET_ATTR_RW(2, 2); 606static ALS_TARGET_ATTR_RW(2, 3); 607static ALS_TARGET_ATTR_RW(2, 4); 608 609#define ALS_THRESH_FALLING_ATTR_RW(_nr) \ 610 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_falling_value, \ 611 S_IRUGO | S_IWUSR, \ 612 show_als_attr, store_als_attr, \ 613 LM3533_ATTR_TYPE_THRESH_FALLING, _nr, 0) 614 615#define ALS_THRESH_RAISING_ATTR_RW(_nr) \ 616 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_raising_value, \ 617 S_IRUGO | S_IWUSR, \ 618 show_als_attr, store_als_attr, \ 619 LM3533_ATTR_TYPE_THRESH_RAISING, _nr, 0) 620/* 621 * ALS Zone thresholds (boundaries) 622 * 623 * in_illuminance0_thresh[0-3]_falling_value 0-255 624 * in_illuminance0_thresh[0-3]_raising_value 0-255 625 */ 626static ALS_THRESH_FALLING_ATTR_RW(0); 627static ALS_THRESH_FALLING_ATTR_RW(1); 628static ALS_THRESH_FALLING_ATTR_RW(2); 629static ALS_THRESH_FALLING_ATTR_RW(3); 630 631static ALS_THRESH_RAISING_ATTR_RW(0); 632static ALS_THRESH_RAISING_ATTR_RW(1); 633static ALS_THRESH_RAISING_ATTR_RW(2); 634static ALS_THRESH_RAISING_ATTR_RW(3); 635 636#define ALS_HYSTERESIS_ATTR_RO(_nr) \ 637 LM3533_ALS_ATTR(in_illuminance0_thresh##_nr##_hysteresis, \ 638 S_IRUGO, show_als_attr, NULL, \ 639 LM3533_ATTR_TYPE_HYSTERESIS, _nr, 0) 640/* 641 * ALS Zone threshold hysteresis 642 * 643 * threshY_hysteresis = threshY_raising - threshY_falling 644 * 645 * in_illuminance0_thresh[0-3]_hysteresis 0-255 646 * in_illuminance0_thresh[0-3]_hysteresis 0-255 647 */ 648static ALS_HYSTERESIS_ATTR_RO(0); 649static ALS_HYSTERESIS_ATTR_RO(1); 650static ALS_HYSTERESIS_ATTR_RO(2); 651static ALS_HYSTERESIS_ATTR_RO(3); 652 653#define ILLUMINANCE_ATTR_RO(_name) \ 654 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO, show_##_name, NULL) 655#define ILLUMINANCE_ATTR_RW(_name) \ 656 DEVICE_ATTR(in_illuminance0_##_name, S_IRUGO | S_IWUSR, \ 657 show_##_name, store_##_name) 658/* 659 * ALS Zone threshold-event enable 660 * 661 * in_illuminance0_thresh_either_en 0,1 662 */ 663static ILLUMINANCE_ATTR_RW(thresh_either_en); 664 665/* 666 * ALS Current Zone 667 * 668 * in_illuminance0_zone 0-4 669 */ 670static ILLUMINANCE_ATTR_RO(zone); 671 672static struct attribute *lm3533_als_event_attributes[] = { 673 &dev_attr_in_illuminance0_thresh_either_en.attr, 674 &lm3533_als_attr_in_illuminance0_thresh0_falling_value.dev_attr.attr, 675 &lm3533_als_attr_in_illuminance0_thresh0_hysteresis.dev_attr.attr, 676 &lm3533_als_attr_in_illuminance0_thresh0_raising_value.dev_attr.attr, 677 &lm3533_als_attr_in_illuminance0_thresh1_falling_value.dev_attr.attr, 678 &lm3533_als_attr_in_illuminance0_thresh1_hysteresis.dev_attr.attr, 679 &lm3533_als_attr_in_illuminance0_thresh1_raising_value.dev_attr.attr, 680 &lm3533_als_attr_in_illuminance0_thresh2_falling_value.dev_attr.attr, 681 &lm3533_als_attr_in_illuminance0_thresh2_hysteresis.dev_attr.attr, 682 &lm3533_als_attr_in_illuminance0_thresh2_raising_value.dev_attr.attr, 683 &lm3533_als_attr_in_illuminance0_thresh3_falling_value.dev_attr.attr, 684 &lm3533_als_attr_in_illuminance0_thresh3_hysteresis.dev_attr.attr, 685 &lm3533_als_attr_in_illuminance0_thresh3_raising_value.dev_attr.attr, 686 NULL 687}; 688 689static const struct attribute_group lm3533_als_event_attribute_group = { 690 .attrs = lm3533_als_event_attributes 691}; 692 693static struct attribute *lm3533_als_attributes[] = { 694 &dev_attr_in_illuminance0_zone.attr, 695 &lm3533_als_attr_out_current0_current0_raw.dev_attr.attr, 696 &lm3533_als_attr_out_current0_current1_raw.dev_attr.attr, 697 &lm3533_als_attr_out_current0_current2_raw.dev_attr.attr, 698 &lm3533_als_attr_out_current0_current3_raw.dev_attr.attr, 699 &lm3533_als_attr_out_current0_current4_raw.dev_attr.attr, 700 &lm3533_als_attr_out_current1_current0_raw.dev_attr.attr, 701 &lm3533_als_attr_out_current1_current1_raw.dev_attr.attr, 702 &lm3533_als_attr_out_current1_current2_raw.dev_attr.attr, 703 &lm3533_als_attr_out_current1_current3_raw.dev_attr.attr, 704 &lm3533_als_attr_out_current1_current4_raw.dev_attr.attr, 705 &lm3533_als_attr_out_current2_current0_raw.dev_attr.attr, 706 &lm3533_als_attr_out_current2_current1_raw.dev_attr.attr, 707 &lm3533_als_attr_out_current2_current2_raw.dev_attr.attr, 708 &lm3533_als_attr_out_current2_current3_raw.dev_attr.attr, 709 &lm3533_als_attr_out_current2_current4_raw.dev_attr.attr, 710 NULL 711}; 712 713static const struct attribute_group lm3533_als_attribute_group = { 714 .attrs = lm3533_als_attributes 715}; 716 717static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode) 718{ 719 u8 mask = LM3533_ALS_INPUT_MODE_MASK; 720 u8 val; 721 int ret; 722 723 if (pwm_mode) 724 val = mask; /* pwm input */ 725 else 726 val = 0; /* analog input */ 727 728 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask); 729 if (ret) { 730 dev_err(&als->pdev->dev, "failed to set input mode %d\n", 731 pwm_mode); 732 return ret; 733 } 734 735 return 0; 736} 737 738static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val) 739{ 740 int ret; 741 742 if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) { 743 dev_err(&als->pdev->dev, "invalid resistor value\n"); 744 return -EINVAL; 745 } 746 747 ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val); 748 if (ret) { 749 dev_err(&als->pdev->dev, "failed to set resistor\n"); 750 return ret; 751 } 752 753 return 0; 754} 755 756static int lm3533_als_setup(struct lm3533_als *als, 757 struct lm3533_als_platform_data *pdata) 758{ 759 int ret; 760 761 ret = lm3533_als_set_input_mode(als, pdata->pwm_mode); 762 if (ret) 763 return ret; 764 765 /* ALS input is always high impedance in PWM-mode. */ 766 if (!pdata->pwm_mode) { 767 ret = lm3533_als_set_resistor(als, pdata->r_select); 768 if (ret) 769 return ret; 770 } 771 772 return 0; 773} 774 775static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev) 776{ 777 u8 mask = LM3533_ALS_INT_ENABLE_MASK; 778 int ret; 779 780 /* Make sure interrupts are disabled. */ 781 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask); 782 if (ret) { 783 dev_err(&als->pdev->dev, "failed to disable interrupts\n"); 784 return ret; 785 } 786 787 ret = request_threaded_irq(als->irq, NULL, lm3533_als_isr, 788 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 789 dev_name(&als->pdev->dev), dev); 790 if (ret) { 791 dev_err(&als->pdev->dev, "failed to request irq %d\n", 792 als->irq); 793 return ret; 794 } 795 796 return 0; 797} 798 799static int lm3533_als_enable(struct lm3533_als *als) 800{ 801 u8 mask = LM3533_ALS_ENABLE_MASK; 802 int ret; 803 804 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask); 805 if (ret) 806 dev_err(&als->pdev->dev, "failed to enable ALS\n"); 807 808 return ret; 809} 810 811static int lm3533_als_disable(struct lm3533_als *als) 812{ 813 u8 mask = LM3533_ALS_ENABLE_MASK; 814 int ret; 815 816 ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask); 817 if (ret) 818 dev_err(&als->pdev->dev, "failed to disable ALS\n"); 819 820 return ret; 821} 822 823static const struct iio_info lm3533_als_info = { 824 .attrs = &lm3533_als_attribute_group, 825 .event_attrs = &lm3533_als_event_attribute_group, 826 .read_raw = &lm3533_als_read_raw, 827}; 828 829static int lm3533_als_probe(struct platform_device *pdev) 830{ 831 struct lm3533 *lm3533; 832 struct lm3533_als_platform_data *pdata; 833 struct lm3533_als *als; 834 struct iio_dev *indio_dev; 835 int ret; 836 837 lm3533 = dev_get_drvdata(pdev->dev.parent); 838 if (!lm3533) 839 return -EINVAL; 840 841 pdata = pdev->dev.platform_data; 842 if (!pdata) { 843 dev_err(&pdev->dev, "no platform data\n"); 844 return -EINVAL; 845 } 846 847 indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als)); 848 if (!indio_dev) 849 return -ENOMEM; 850 851 indio_dev->info = &lm3533_als_info; 852 indio_dev->channels = lm3533_als_channels; 853 indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels); 854 indio_dev->name = dev_name(&pdev->dev); 855 iio_device_set_parent(indio_dev, pdev->dev.parent); 856 indio_dev->modes = INDIO_DIRECT_MODE; 857 858 als = iio_priv(indio_dev); 859 als->lm3533 = lm3533; 860 als->pdev = pdev; 861 als->irq = lm3533->irq; 862 atomic_set(&als->zone, 0); 863 mutex_init(&als->thresh_mutex); 864 865 platform_set_drvdata(pdev, indio_dev); 866 867 if (als->irq) { 868 ret = lm3533_als_setup_irq(als, indio_dev); 869 if (ret) 870 return ret; 871 } 872 873 ret = lm3533_als_setup(als, pdata); 874 if (ret) 875 goto err_free_irq; 876 877 ret = lm3533_als_enable(als); 878 if (ret) 879 goto err_free_irq; 880 881 ret = iio_device_register(indio_dev); 882 if (ret) { 883 dev_err(&pdev->dev, "failed to register ALS\n"); 884 goto err_disable; 885 } 886 887 return 0; 888 889err_disable: 890 lm3533_als_disable(als); 891err_free_irq: 892 if (als->irq) 893 free_irq(als->irq, indio_dev); 894 895 return ret; 896} 897 898static int lm3533_als_remove(struct platform_device *pdev) 899{ 900 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 901 struct lm3533_als *als = iio_priv(indio_dev); 902 903 lm3533_als_set_int_mode(indio_dev, false); 904 iio_device_unregister(indio_dev); 905 lm3533_als_disable(als); 906 if (als->irq) 907 free_irq(als->irq, indio_dev); 908 909 return 0; 910} 911 912static struct platform_driver lm3533_als_driver = { 913 .driver = { 914 .name = "lm3533-als", 915 }, 916 .probe = lm3533_als_probe, 917 .remove = lm3533_als_remove, 918}; 919module_platform_driver(lm3533_als_driver); 920 921MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); 922MODULE_DESCRIPTION("LM3533 Ambient Light Sensor driver"); 923MODULE_LICENSE("GPL"); 924MODULE_ALIAS("platform:lm3533-als");