root/drivers/iio/light/apds9300.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. apds9300_calculate_lux
  2. apds9300_get_adc_val
  3. apds9300_set_thresh_low
  4. apds9300_set_thresh_hi
  5. apds9300_set_intr_state
  6. apds9300_set_power_state
  7. apds9300_clear_intr
  8. apds9300_chip_init
  9. apds9300_read_raw
  10. apds9300_read_thresh
  11. apds9300_write_thresh
  12. apds9300_read_interrupt_config
  13. apds9300_write_interrupt_config
  14. apds9300_interrupt_handler
  15. apds9300_probe
  16. apds9300_remove
  17. apds9300_suspend
  18. apds9300_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * apds9300.c - IIO driver for Avago APDS9300 ambient light sensor
   4  *
   5  * Copyright 2013 Oleksandr Kravchenko <o.v.kravchenko@globallogic.com>
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/slab.h>
  10 #include <linux/pm.h>
  11 #include <linux/i2c.h>
  12 #include <linux/err.h>
  13 #include <linux/mutex.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/iio/iio.h>
  16 #include <linux/iio/sysfs.h>
  17 #include <linux/iio/events.h>
  18 
  19 #define APDS9300_DRV_NAME "apds9300"
  20 #define APDS9300_IRQ_NAME "apds9300_event"
  21 
  22 /* Command register bits */
  23 #define APDS9300_CMD    BIT(7) /* Select command register. Must write as 1 */
  24 #define APDS9300_WORD   BIT(5) /* I2C write/read: if 1 word, if 0 byte */
  25 #define APDS9300_CLEAR  BIT(6) /* Interrupt clear. Clears pending interrupt */
  26 
  27 /* Register set */
  28 #define APDS9300_CONTROL        0x00 /* Control of basic functions */
  29 #define APDS9300_THRESHLOWLOW   0x02 /* Low byte of low interrupt threshold */
  30 #define APDS9300_THRESHHIGHLOW  0x04 /* Low byte of high interrupt threshold */
  31 #define APDS9300_INTERRUPT      0x06 /* Interrupt control */
  32 #define APDS9300_DATA0LOW       0x0c /* Low byte of ADC channel 0 */
  33 #define APDS9300_DATA1LOW       0x0e /* Low byte of ADC channel 1 */
  34 
  35 /* Power on/off value for APDS9300_CONTROL register */
  36 #define APDS9300_POWER_ON       0x03
  37 #define APDS9300_POWER_OFF      0x00
  38 
  39 /* Interrupts */
  40 #define APDS9300_INTR_ENABLE    0x10
  41 /* Interrupt Persist Function: Any value outside of threshold range */
  42 #define APDS9300_THRESH_INTR    0x01
  43 
  44 #define APDS9300_THRESH_MAX     0xffff /* Max threshold value */
  45 
  46 struct apds9300_data {
  47         struct i2c_client *client;
  48         struct mutex mutex;
  49         int power_state;
  50         int thresh_low;
  51         int thresh_hi;
  52         int intr_en;
  53 };
  54 
  55 /* Lux calculation */
  56 
  57 /* Calculated values 1000 * (CH1/CH0)^1.4 for CH1/CH0 from 0 to 0.52 */
  58 static const u16 apds9300_lux_ratio[] = {
  59         0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91,
  60         98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203,
  61         212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337,
  62         347, 358, 368, 379, 390, 400,
  63 };
  64 
  65 static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1)
  66 {
  67         unsigned long lux, tmp;
  68 
  69         /* avoid division by zero */
  70         if (ch0 == 0)
  71                 return 0;
  72 
  73         tmp = DIV_ROUND_UP(ch1 * 100, ch0);
  74         if (tmp <= 52) {
  75                 lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0
  76                                 * apds9300_lux_ratio[tmp] * 5930ull, 1000);
  77         } else if (tmp <= 65) {
  78                 lux = 2290 * ch0 - 2910 * ch1;
  79         } else if (tmp <= 80) {
  80                 lux = 1570 * ch0 - 1800 * ch1;
  81         } else if (tmp <= 130) {
  82                 lux = 338 * ch0 - 260 * ch1;
  83         } else {
  84                 lux = 0;
  85         }
  86 
  87         return lux / 100000;
  88 }
  89 
  90 static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number)
  91 {
  92         int ret;
  93         u8 flags = APDS9300_CMD | APDS9300_WORD;
  94 
  95         if (!data->power_state)
  96                 return -EBUSY;
  97 
  98         /* Select ADC0 or ADC1 data register */
  99         flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW;
 100 
 101         ret = i2c_smbus_read_word_data(data->client, flags);
 102         if (ret < 0)
 103                 dev_err(&data->client->dev,
 104                         "failed to read ADC%d value\n", adc_number);
 105 
 106         return ret;
 107 }
 108 
 109 static int apds9300_set_thresh_low(struct apds9300_data *data, int value)
 110 {
 111         int ret;
 112 
 113         if (!data->power_state)
 114                 return -EBUSY;
 115 
 116         if (value > APDS9300_THRESH_MAX)
 117                 return -EINVAL;
 118 
 119         ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW
 120                         | APDS9300_CMD | APDS9300_WORD, value);
 121         if (ret) {
 122                 dev_err(&data->client->dev, "failed to set thresh_low\n");
 123                 return ret;
 124         }
 125         data->thresh_low = value;
 126 
 127         return 0;
 128 }
 129 
 130 static int apds9300_set_thresh_hi(struct apds9300_data *data, int value)
 131 {
 132         int ret;
 133 
 134         if (!data->power_state)
 135                 return -EBUSY;
 136 
 137         if (value > APDS9300_THRESH_MAX)
 138                 return -EINVAL;
 139 
 140         ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW
 141                         | APDS9300_CMD | APDS9300_WORD, value);
 142         if (ret) {
 143                 dev_err(&data->client->dev, "failed to set thresh_hi\n");
 144                 return ret;
 145         }
 146         data->thresh_hi = value;
 147 
 148         return 0;
 149 }
 150 
 151 static int apds9300_set_intr_state(struct apds9300_data *data, int state)
 152 {
 153         int ret;
 154         u8 cmd;
 155 
 156         if (!data->power_state)
 157                 return -EBUSY;
 158 
 159         cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00;
 160         ret = i2c_smbus_write_byte_data(data->client,
 161                         APDS9300_INTERRUPT | APDS9300_CMD, cmd);
 162         if (ret) {
 163                 dev_err(&data->client->dev,
 164                         "failed to set interrupt state %d\n", state);
 165                 return ret;
 166         }
 167         data->intr_en = state;
 168 
 169         return 0;
 170 }
 171 
 172 static int apds9300_set_power_state(struct apds9300_data *data, int state)
 173 {
 174         int ret;
 175         u8 cmd;
 176 
 177         cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
 178         ret = i2c_smbus_write_byte_data(data->client,
 179                         APDS9300_CONTROL | APDS9300_CMD, cmd);
 180         if (ret) {
 181                 dev_err(&data->client->dev,
 182                         "failed to set power state %d\n", state);
 183                 return ret;
 184         }
 185         data->power_state = state;
 186 
 187         return 0;
 188 }
 189 
 190 static void apds9300_clear_intr(struct apds9300_data *data)
 191 {
 192         int ret;
 193 
 194         ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD);
 195         if (ret < 0)
 196                 dev_err(&data->client->dev, "failed to clear interrupt\n");
 197 }
 198 
 199 static int apds9300_chip_init(struct apds9300_data *data)
 200 {
 201         int ret;
 202 
 203         /* Need to set power off to ensure that the chip is off */
 204         ret = apds9300_set_power_state(data, 0);
 205         if (ret < 0)
 206                 goto err;
 207         /*
 208          * Probe the chip. To do so we try to power up the device and then to
 209          * read back the 0x03 code
 210          */
 211         ret = apds9300_set_power_state(data, 1);
 212         if (ret < 0)
 213                 goto err;
 214         ret = i2c_smbus_read_byte_data(data->client,
 215                         APDS9300_CONTROL | APDS9300_CMD);
 216         if (ret != APDS9300_POWER_ON) {
 217                 ret = -ENODEV;
 218                 goto err;
 219         }
 220         /*
 221          * Disable interrupt to ensure thai it is doesn't enable
 222          * i.e. after device soft reset
 223          */
 224         ret = apds9300_set_intr_state(data, 0);
 225         if (ret < 0)
 226                 goto err;
 227 
 228         return 0;
 229 
 230 err:
 231         dev_err(&data->client->dev, "failed to init the chip\n");
 232         return ret;
 233 }
 234 
 235 static int apds9300_read_raw(struct iio_dev *indio_dev,
 236                 struct iio_chan_spec const *chan, int *val, int *val2,
 237                 long mask)
 238 {
 239         int ch0, ch1, ret = -EINVAL;
 240         struct apds9300_data *data = iio_priv(indio_dev);
 241 
 242         mutex_lock(&data->mutex);
 243         switch (chan->type) {
 244         case IIO_LIGHT:
 245                 ch0 = apds9300_get_adc_val(data, 0);
 246                 if (ch0 < 0) {
 247                         ret = ch0;
 248                         break;
 249                 }
 250                 ch1 = apds9300_get_adc_val(data, 1);
 251                 if (ch1 < 0) {
 252                         ret = ch1;
 253                         break;
 254                 }
 255                 *val = apds9300_calculate_lux(ch0, ch1);
 256                 ret = IIO_VAL_INT;
 257                 break;
 258         case IIO_INTENSITY:
 259                 ret = apds9300_get_adc_val(data, chan->channel);
 260                 if (ret < 0)
 261                         break;
 262                 *val = ret;
 263                 ret = IIO_VAL_INT;
 264                 break;
 265         default:
 266                 break;
 267         }
 268         mutex_unlock(&data->mutex);
 269 
 270         return ret;
 271 }
 272 
 273 static int apds9300_read_thresh(struct iio_dev *indio_dev,
 274                 const struct iio_chan_spec *chan, enum iio_event_type type,
 275                 enum iio_event_direction dir, enum iio_event_info info,
 276                 int *val, int *val2)
 277 {
 278         struct apds9300_data *data = iio_priv(indio_dev);
 279 
 280         switch (dir) {
 281         case IIO_EV_DIR_RISING:
 282                 *val = data->thresh_hi;
 283                 break;
 284         case IIO_EV_DIR_FALLING:
 285                 *val = data->thresh_low;
 286                 break;
 287         default:
 288                 return -EINVAL;
 289         }
 290 
 291         return IIO_VAL_INT;
 292 }
 293 
 294 static int apds9300_write_thresh(struct iio_dev *indio_dev,
 295                 const struct iio_chan_spec *chan, enum iio_event_type type,
 296                 enum iio_event_direction dir, enum iio_event_info info, int val,
 297                 int val2)
 298 {
 299         struct apds9300_data *data = iio_priv(indio_dev);
 300         int ret;
 301 
 302         mutex_lock(&data->mutex);
 303         if (dir == IIO_EV_DIR_RISING)
 304                 ret = apds9300_set_thresh_hi(data, val);
 305         else
 306                 ret = apds9300_set_thresh_low(data, val);
 307         mutex_unlock(&data->mutex);
 308 
 309         return ret;
 310 }
 311 
 312 static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
 313                 const struct iio_chan_spec *chan,
 314                 enum iio_event_type type,
 315                 enum iio_event_direction dir)
 316 {
 317         struct apds9300_data *data = iio_priv(indio_dev);
 318 
 319         return data->intr_en;
 320 }
 321 
 322 static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
 323                 const struct iio_chan_spec *chan, enum iio_event_type type,
 324                 enum iio_event_direction dir, int state)
 325 {
 326         struct apds9300_data *data = iio_priv(indio_dev);
 327         int ret;
 328 
 329         mutex_lock(&data->mutex);
 330         ret = apds9300_set_intr_state(data, state);
 331         mutex_unlock(&data->mutex);
 332 
 333         return ret;
 334 }
 335 
 336 static const struct iio_info apds9300_info_no_irq = {
 337         .read_raw       = apds9300_read_raw,
 338 };
 339 
 340 static const struct iio_info apds9300_info = {
 341         .read_raw               = apds9300_read_raw,
 342         .read_event_value       = apds9300_read_thresh,
 343         .write_event_value      = apds9300_write_thresh,
 344         .read_event_config      = apds9300_read_interrupt_config,
 345         .write_event_config     = apds9300_write_interrupt_config,
 346 };
 347 
 348 static const struct iio_event_spec apds9300_event_spec[] = {
 349         {
 350                 .type = IIO_EV_TYPE_THRESH,
 351                 .dir = IIO_EV_DIR_RISING,
 352                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 353                         BIT(IIO_EV_INFO_ENABLE),
 354         }, {
 355                 .type = IIO_EV_TYPE_THRESH,
 356                 .dir = IIO_EV_DIR_FALLING,
 357                 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
 358                         BIT(IIO_EV_INFO_ENABLE),
 359         },
 360 };
 361 
 362 static const struct iio_chan_spec apds9300_channels[] = {
 363         {
 364                 .type = IIO_LIGHT,
 365                 .channel = 0,
 366                 .indexed = true,
 367                 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
 368         }, {
 369                 .type = IIO_INTENSITY,
 370                 .channel = 0,
 371                 .channel2 = IIO_MOD_LIGHT_BOTH,
 372                 .indexed = true,
 373                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 374                 .event_spec = apds9300_event_spec,
 375                 .num_event_specs = ARRAY_SIZE(apds9300_event_spec),
 376         }, {
 377                 .type = IIO_INTENSITY,
 378                 .channel = 1,
 379                 .channel2 = IIO_MOD_LIGHT_IR,
 380                 .indexed = true,
 381                 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 382         },
 383 };
 384 
 385 static irqreturn_t apds9300_interrupt_handler(int irq, void *private)
 386 {
 387         struct iio_dev *dev_info = private;
 388         struct apds9300_data *data = iio_priv(dev_info);
 389 
 390         iio_push_event(dev_info,
 391                        IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
 392                                             IIO_EV_TYPE_THRESH,
 393                                             IIO_EV_DIR_EITHER),
 394                        iio_get_time_ns(dev_info));
 395 
 396         apds9300_clear_intr(data);
 397 
 398         return IRQ_HANDLED;
 399 }
 400 
 401 static int apds9300_probe(struct i2c_client *client,
 402                 const struct i2c_device_id *id)
 403 {
 404         struct apds9300_data *data;
 405         struct iio_dev *indio_dev;
 406         int ret;
 407 
 408         indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 409         if (!indio_dev)
 410                 return -ENOMEM;
 411 
 412         data = iio_priv(indio_dev);
 413         i2c_set_clientdata(client, indio_dev);
 414         data->client = client;
 415 
 416         ret = apds9300_chip_init(data);
 417         if (ret < 0)
 418                 goto err;
 419 
 420         mutex_init(&data->mutex);
 421 
 422         indio_dev->dev.parent = &client->dev;
 423         indio_dev->channels = apds9300_channels;
 424         indio_dev->num_channels = ARRAY_SIZE(apds9300_channels);
 425         indio_dev->name = APDS9300_DRV_NAME;
 426         indio_dev->modes = INDIO_DIRECT_MODE;
 427 
 428         if (client->irq)
 429                 indio_dev->info = &apds9300_info;
 430         else
 431                 indio_dev->info = &apds9300_info_no_irq;
 432 
 433         if (client->irq) {
 434                 ret = devm_request_threaded_irq(&client->dev, client->irq,
 435                                 NULL, apds9300_interrupt_handler,
 436                                 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 437                                 APDS9300_IRQ_NAME, indio_dev);
 438                 if (ret) {
 439                         dev_err(&client->dev, "irq request error %d\n", -ret);
 440                         goto err;
 441                 }
 442         }
 443 
 444         ret = iio_device_register(indio_dev);
 445         if (ret < 0)
 446                 goto err;
 447 
 448         return 0;
 449 
 450 err:
 451         /* Ensure that power off in case of error */
 452         apds9300_set_power_state(data, 0);
 453         return ret;
 454 }
 455 
 456 static int apds9300_remove(struct i2c_client *client)
 457 {
 458         struct iio_dev *indio_dev = i2c_get_clientdata(client);
 459         struct apds9300_data *data = iio_priv(indio_dev);
 460 
 461         iio_device_unregister(indio_dev);
 462 
 463         /* Ensure that power off and interrupts are disabled */
 464         apds9300_set_intr_state(data, 0);
 465         apds9300_set_power_state(data, 0);
 466 
 467         return 0;
 468 }
 469 
 470 #ifdef CONFIG_PM_SLEEP
 471 static int apds9300_suspend(struct device *dev)
 472 {
 473         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 474         struct apds9300_data *data = iio_priv(indio_dev);
 475         int ret;
 476 
 477         mutex_lock(&data->mutex);
 478         ret = apds9300_set_power_state(data, 0);
 479         mutex_unlock(&data->mutex);
 480 
 481         return ret;
 482 }
 483 
 484 static int apds9300_resume(struct device *dev)
 485 {
 486         struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
 487         struct apds9300_data *data = iio_priv(indio_dev);
 488         int ret;
 489 
 490         mutex_lock(&data->mutex);
 491         ret = apds9300_set_power_state(data, 1);
 492         mutex_unlock(&data->mutex);
 493 
 494         return ret;
 495 }
 496 
 497 static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
 498 #define APDS9300_PM_OPS (&apds9300_pm_ops)
 499 #else
 500 #define APDS9300_PM_OPS NULL
 501 #endif
 502 
 503 static const struct i2c_device_id apds9300_id[] = {
 504         { APDS9300_DRV_NAME, 0 },
 505         { }
 506 };
 507 
 508 MODULE_DEVICE_TABLE(i2c, apds9300_id);
 509 
 510 static struct i2c_driver apds9300_driver = {
 511         .driver = {
 512                 .name   = APDS9300_DRV_NAME,
 513                 .pm     = APDS9300_PM_OPS,
 514         },
 515         .probe          = apds9300_probe,
 516         .remove         = apds9300_remove,
 517         .id_table       = apds9300_id,
 518 };
 519 
 520 module_i2c_driver(apds9300_driver);
 521 
 522 MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>");
 523 MODULE_AUTHOR("GlobalLogic inc.");
 524 MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver");
 525 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */