linux/drivers/iio/light/tcs3472.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter
   4 *
   5 * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
   6 *
   7 * Color light sensor with 16-bit channels for red, green, blue, clear);
   8 * 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
   9 * TCS34727)
  10 *
  11 * Datasheet: http://ams.com/eng/content/download/319364/1117183/file/TCS3472_Datasheet_EN_v2.pdf
  12 *
  13 * TODO: wait time
  14 */
  15
  16#include <linux/module.h>
  17#include <linux/i2c.h>
  18#include <linux/delay.h>
  19#include <linux/pm.h>
  20
  21#include <linux/iio/iio.h>
  22#include <linux/iio/sysfs.h>
  23#include <linux/iio/events.h>
  24#include <linux/iio/trigger_consumer.h>
  25#include <linux/iio/buffer.h>
  26#include <linux/iio/triggered_buffer.h>
  27
  28#define TCS3472_DRV_NAME "tcs3472"
  29
  30#define TCS3472_COMMAND BIT(7)
  31#define TCS3472_AUTO_INCR BIT(5)
  32#define TCS3472_SPECIAL_FUNC (BIT(5) | BIT(6))
  33
  34#define TCS3472_INTR_CLEAR (TCS3472_COMMAND | TCS3472_SPECIAL_FUNC | 0x06)
  35
  36#define TCS3472_ENABLE (TCS3472_COMMAND | 0x00)
  37#define TCS3472_ATIME (TCS3472_COMMAND | 0x01)
  38#define TCS3472_WTIME (TCS3472_COMMAND | 0x03)
  39#define TCS3472_AILT (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x04)
  40#define TCS3472_AIHT (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x06)
  41#define TCS3472_PERS (TCS3472_COMMAND | 0x0c)
  42#define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d)
  43#define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f)
  44#define TCS3472_ID (TCS3472_COMMAND | 0x12)
  45#define TCS3472_STATUS (TCS3472_COMMAND | 0x13)
  46#define TCS3472_CDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x14)
  47#define TCS3472_RDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x16)
  48#define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18)
  49#define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a)
  50
  51#define TCS3472_STATUS_AINT BIT(4)
  52#define TCS3472_STATUS_AVALID BIT(0)
  53#define TCS3472_ENABLE_AIEN BIT(4)
  54#define TCS3472_ENABLE_AEN BIT(1)
  55#define TCS3472_ENABLE_PON BIT(0)
  56#define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1))
  57
  58struct tcs3472_data {
  59        struct i2c_client *client;
  60        struct mutex lock;
  61        u16 low_thresh;
  62        u16 high_thresh;
  63        u8 enable;
  64        u8 control;
  65        u8 atime;
  66        u8 apers;
  67        /* Ensure timestamp is naturally aligned */
  68        struct {
  69                u16 chans[4];
  70                s64 timestamp __aligned(8);
  71        } scan;
  72};
  73
  74static const struct iio_event_spec tcs3472_events[] = {
  75        {
  76                .type = IIO_EV_TYPE_THRESH,
  77                .dir = IIO_EV_DIR_RISING,
  78                .mask_separate = BIT(IIO_EV_INFO_VALUE),
  79        }, {
  80                .type = IIO_EV_TYPE_THRESH,
  81                .dir = IIO_EV_DIR_FALLING,
  82                .mask_separate = BIT(IIO_EV_INFO_VALUE),
  83        }, {
  84                .type = IIO_EV_TYPE_THRESH,
  85                .dir = IIO_EV_DIR_EITHER,
  86                .mask_separate = BIT(IIO_EV_INFO_ENABLE) |
  87                                 BIT(IIO_EV_INFO_PERIOD),
  88        },
  89};
  90
  91#define TCS3472_CHANNEL(_color, _si, _addr) { \
  92        .type = IIO_INTENSITY, \
  93        .modified = 1, \
  94        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  95        .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
  96                BIT(IIO_CHAN_INFO_INT_TIME), \
  97        .channel2 = IIO_MOD_LIGHT_##_color, \
  98        .address = _addr, \
  99        .scan_index = _si, \
 100        .scan_type = { \
 101                .sign = 'u', \
 102                .realbits = 16, \
 103                .storagebits = 16, \
 104                .endianness = IIO_CPU, \
 105        }, \
 106        .event_spec = _si ? NULL : tcs3472_events, \
 107        .num_event_specs = _si ? 0 : ARRAY_SIZE(tcs3472_events), \
 108}
 109
 110static const int tcs3472_agains[] = { 1, 4, 16, 60 };
 111
 112static const struct iio_chan_spec tcs3472_channels[] = {
 113        TCS3472_CHANNEL(CLEAR, 0, TCS3472_CDATA),
 114        TCS3472_CHANNEL(RED, 1, TCS3472_RDATA),
 115        TCS3472_CHANNEL(GREEN, 2, TCS3472_GDATA),
 116        TCS3472_CHANNEL(BLUE, 3, TCS3472_BDATA),
 117        IIO_CHAN_SOFT_TIMESTAMP(4),
 118};
 119
 120static int tcs3472_req_data(struct tcs3472_data *data)
 121{
 122        int tries = 50;
 123        int ret;
 124
 125        while (tries--) {
 126                ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
 127                if (ret < 0)
 128                        return ret;
 129                if (ret & TCS3472_STATUS_AVALID)
 130                        break;
 131                msleep(20);
 132        }
 133
 134        if (tries < 0) {
 135                dev_err(&data->client->dev, "data not ready\n");
 136                return -EIO;
 137        }
 138
 139        return 0;
 140}
 141
 142static int tcs3472_read_raw(struct iio_dev *indio_dev,
 143                           struct iio_chan_spec const *chan,
 144                           int *val, int *val2, long mask)
 145{
 146        struct tcs3472_data *data = iio_priv(indio_dev);
 147        int ret;
 148
 149        switch (mask) {
 150        case IIO_CHAN_INFO_RAW:
 151                ret = iio_device_claim_direct_mode(indio_dev);
 152                if (ret)
 153                        return ret;
 154                ret = tcs3472_req_data(data);
 155                if (ret < 0) {
 156                        iio_device_release_direct_mode(indio_dev);
 157                        return ret;
 158                }
 159                ret = i2c_smbus_read_word_data(data->client, chan->address);
 160                iio_device_release_direct_mode(indio_dev);
 161                if (ret < 0)
 162                        return ret;
 163                *val = ret;
 164                return IIO_VAL_INT;
 165        case IIO_CHAN_INFO_CALIBSCALE:
 166                *val = tcs3472_agains[data->control &
 167                        TCS3472_CONTROL_AGAIN_MASK];
 168                return IIO_VAL_INT;
 169        case IIO_CHAN_INFO_INT_TIME:
 170                *val = 0;
 171                *val2 = (256 - data->atime) * 2400;
 172                return IIO_VAL_INT_PLUS_MICRO;
 173        }
 174        return -EINVAL;
 175}
 176
 177static int tcs3472_write_raw(struct iio_dev *indio_dev,
 178                               struct iio_chan_spec const *chan,
 179                               int val, int val2, long mask)
 180{
 181        struct tcs3472_data *data = iio_priv(indio_dev);
 182        int i;
 183
 184        switch (mask) {
 185        case IIO_CHAN_INFO_CALIBSCALE:
 186                if (val2 != 0)
 187                        return -EINVAL;
 188                for (i = 0; i < ARRAY_SIZE(tcs3472_agains); i++) {
 189                        if (val == tcs3472_agains[i]) {
 190                                data->control &= ~TCS3472_CONTROL_AGAIN_MASK;
 191                                data->control |= i;
 192                                return i2c_smbus_write_byte_data(
 193                                        data->client, TCS3472_CONTROL,
 194                                        data->control);
 195                        }
 196                }
 197                return -EINVAL;
 198        case IIO_CHAN_INFO_INT_TIME:
 199                if (val != 0)
 200                        return -EINVAL;
 201                for (i = 0; i < 256; i++) {
 202                        if (val2 == (256 - i) * 2400) {
 203                                data->atime = i;
 204                                return i2c_smbus_write_byte_data(
 205                                        data->client, TCS3472_ATIME,
 206                                        data->atime);
 207                        }
 208
 209                }
 210                return -EINVAL;
 211        }
 212        return -EINVAL;
 213}
 214
 215/*
 216 * Translation from APERS field value to the number of consecutive out-of-range
 217 * clear channel values before an interrupt is generated
 218 */
 219static const int tcs3472_intr_pers[] = {
 220        0, 1, 2, 3, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60
 221};
 222
 223static int tcs3472_read_event(struct iio_dev *indio_dev,
 224        const struct iio_chan_spec *chan, enum iio_event_type type,
 225        enum iio_event_direction dir, enum iio_event_info info, int *val,
 226        int *val2)
 227{
 228        struct tcs3472_data *data = iio_priv(indio_dev);
 229        int ret;
 230        unsigned int period;
 231
 232        mutex_lock(&data->lock);
 233
 234        switch (info) {
 235        case IIO_EV_INFO_VALUE:
 236                *val = (dir == IIO_EV_DIR_RISING) ?
 237                        data->high_thresh : data->low_thresh;
 238                ret = IIO_VAL_INT;
 239                break;
 240        case IIO_EV_INFO_PERIOD:
 241                period = (256 - data->atime) * 2400 *
 242                        tcs3472_intr_pers[data->apers];
 243                *val = period / USEC_PER_SEC;
 244                *val2 = period % USEC_PER_SEC;
 245                ret = IIO_VAL_INT_PLUS_MICRO;
 246                break;
 247        default:
 248                ret = -EINVAL;
 249                break;
 250        }
 251
 252        mutex_unlock(&data->lock);
 253
 254        return ret;
 255}
 256
 257static int tcs3472_write_event(struct iio_dev *indio_dev,
 258        const struct iio_chan_spec *chan, enum iio_event_type type,
 259        enum iio_event_direction dir, enum iio_event_info info, int val,
 260        int val2)
 261{
 262        struct tcs3472_data *data = iio_priv(indio_dev);
 263        int ret;
 264        u8 command;
 265        int period;
 266        int i;
 267
 268        mutex_lock(&data->lock);
 269        switch (info) {
 270        case IIO_EV_INFO_VALUE:
 271                switch (dir) {
 272                case IIO_EV_DIR_RISING:
 273                        command = TCS3472_AIHT;
 274                        break;
 275                case IIO_EV_DIR_FALLING:
 276                        command = TCS3472_AILT;
 277                        break;
 278                default:
 279                        ret = -EINVAL;
 280                        goto error;
 281                }
 282                ret = i2c_smbus_write_word_data(data->client, command, val);
 283                if (ret)
 284                        goto error;
 285
 286                if (dir == IIO_EV_DIR_RISING)
 287                        data->high_thresh = val;
 288                else
 289                        data->low_thresh = val;
 290                break;
 291        case IIO_EV_INFO_PERIOD:
 292                period = val * USEC_PER_SEC + val2;
 293                for (i = 1; i < ARRAY_SIZE(tcs3472_intr_pers) - 1; i++) {
 294                        if (period <= (256 - data->atime) * 2400 *
 295                                        tcs3472_intr_pers[i])
 296                                break;
 297                }
 298                ret = i2c_smbus_write_byte_data(data->client, TCS3472_PERS, i);
 299                if (ret)
 300                        goto error;
 301
 302                data->apers = i;
 303                break;
 304        default:
 305                ret = -EINVAL;
 306                break;
 307        }
 308error:
 309        mutex_unlock(&data->lock);
 310
 311        return ret;
 312}
 313
 314static int tcs3472_read_event_config(struct iio_dev *indio_dev,
 315        const struct iio_chan_spec *chan, enum iio_event_type type,
 316        enum iio_event_direction dir)
 317{
 318        struct tcs3472_data *data = iio_priv(indio_dev);
 319        int ret;
 320
 321        mutex_lock(&data->lock);
 322        ret = !!(data->enable & TCS3472_ENABLE_AIEN);
 323        mutex_unlock(&data->lock);
 324
 325        return ret;
 326}
 327
 328static int tcs3472_write_event_config(struct iio_dev *indio_dev,
 329        const struct iio_chan_spec *chan, enum iio_event_type type,
 330        enum iio_event_direction dir, int state)
 331{
 332        struct tcs3472_data *data = iio_priv(indio_dev);
 333        int ret = 0;
 334        u8 enable_old;
 335
 336        mutex_lock(&data->lock);
 337
 338        enable_old = data->enable;
 339
 340        if (state)
 341                data->enable |= TCS3472_ENABLE_AIEN;
 342        else
 343                data->enable &= ~TCS3472_ENABLE_AIEN;
 344
 345        if (enable_old != data->enable) {
 346                ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
 347                                                data->enable);
 348                if (ret)
 349                        data->enable = enable_old;
 350        }
 351        mutex_unlock(&data->lock);
 352
 353        return ret;
 354}
 355
 356static irqreturn_t tcs3472_event_handler(int irq, void *priv)
 357{
 358        struct iio_dev *indio_dev = priv;
 359        struct tcs3472_data *data = iio_priv(indio_dev);
 360        int ret;
 361
 362        ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
 363        if (ret >= 0 && (ret & TCS3472_STATUS_AINT)) {
 364                iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
 365                                                IIO_EV_TYPE_THRESH,
 366                                                IIO_EV_DIR_EITHER),
 367                                iio_get_time_ns(indio_dev));
 368
 369                i2c_smbus_read_byte_data(data->client, TCS3472_INTR_CLEAR);
 370        }
 371
 372        return IRQ_HANDLED;
 373}
 374
 375static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
 376{
 377        struct iio_poll_func *pf = p;
 378        struct iio_dev *indio_dev = pf->indio_dev;
 379        struct tcs3472_data *data = iio_priv(indio_dev);
 380        int i, j = 0;
 381
 382        int ret = tcs3472_req_data(data);
 383        if (ret < 0)
 384                goto done;
 385
 386        for_each_set_bit(i, indio_dev->active_scan_mask,
 387                indio_dev->masklength) {
 388                ret = i2c_smbus_read_word_data(data->client,
 389                        TCS3472_CDATA + 2*i);
 390                if (ret < 0)
 391                        goto done;
 392
 393                data->scan.chans[j++] = ret;
 394        }
 395
 396        iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
 397                iio_get_time_ns(indio_dev));
 398
 399done:
 400        iio_trigger_notify_done(indio_dev->trig);
 401
 402        return IRQ_HANDLED;
 403}
 404
 405static ssize_t tcs3472_show_int_time_available(struct device *dev,
 406                                        struct device_attribute *attr,
 407                                        char *buf)
 408{
 409        size_t len = 0;
 410        int i;
 411
 412        for (i = 1; i <= 256; i++)
 413                len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
 414                        2400 * i);
 415
 416        /* replace trailing space by newline */
 417        buf[len - 1] = '\n';
 418
 419        return len;
 420}
 421
 422static IIO_CONST_ATTR(calibscale_available, "1 4 16 60");
 423static IIO_DEV_ATTR_INT_TIME_AVAIL(tcs3472_show_int_time_available);
 424
 425static struct attribute *tcs3472_attributes[] = {
 426        &iio_const_attr_calibscale_available.dev_attr.attr,
 427        &iio_dev_attr_integration_time_available.dev_attr.attr,
 428        NULL
 429};
 430
 431static const struct attribute_group tcs3472_attribute_group = {
 432        .attrs = tcs3472_attributes,
 433};
 434
 435static const struct iio_info tcs3472_info = {
 436        .read_raw = tcs3472_read_raw,
 437        .write_raw = tcs3472_write_raw,
 438        .read_event_value = tcs3472_read_event,
 439        .write_event_value = tcs3472_write_event,
 440        .read_event_config = tcs3472_read_event_config,
 441        .write_event_config = tcs3472_write_event_config,
 442        .attrs = &tcs3472_attribute_group,
 443};
 444
 445static int tcs3472_probe(struct i2c_client *client,
 446                           const struct i2c_device_id *id)
 447{
 448        struct tcs3472_data *data;
 449        struct iio_dev *indio_dev;
 450        int ret;
 451
 452        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 453        if (indio_dev == NULL)
 454                return -ENOMEM;
 455
 456        data = iio_priv(indio_dev);
 457        i2c_set_clientdata(client, indio_dev);
 458        data->client = client;
 459        mutex_init(&data->lock);
 460
 461        indio_dev->info = &tcs3472_info;
 462        indio_dev->name = TCS3472_DRV_NAME;
 463        indio_dev->channels = tcs3472_channels;
 464        indio_dev->num_channels = ARRAY_SIZE(tcs3472_channels);
 465        indio_dev->modes = INDIO_DIRECT_MODE;
 466
 467        ret = i2c_smbus_read_byte_data(data->client, TCS3472_ID);
 468        if (ret < 0)
 469                return ret;
 470
 471        if (ret == 0x44)
 472                dev_info(&client->dev, "TCS34721/34725 found\n");
 473        else if (ret == 0x4d)
 474                dev_info(&client->dev, "TCS34723/34727 found\n");
 475        else
 476                return -ENODEV;
 477
 478        ret = i2c_smbus_read_byte_data(data->client, TCS3472_CONTROL);
 479        if (ret < 0)
 480                return ret;
 481        data->control = ret;
 482
 483        ret = i2c_smbus_read_byte_data(data->client, TCS3472_ATIME);
 484        if (ret < 0)
 485                return ret;
 486        data->atime = ret;
 487
 488        ret = i2c_smbus_read_word_data(data->client, TCS3472_AILT);
 489        if (ret < 0)
 490                return ret;
 491        data->low_thresh = ret;
 492
 493        ret = i2c_smbus_read_word_data(data->client, TCS3472_AIHT);
 494        if (ret < 0)
 495                return ret;
 496        data->high_thresh = ret;
 497
 498        data->apers = 1;
 499        ret = i2c_smbus_write_byte_data(data->client, TCS3472_PERS,
 500                                        data->apers);
 501        if (ret < 0)
 502                return ret;
 503
 504        ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE);
 505        if (ret < 0)
 506                return ret;
 507
 508        /* enable device */
 509        data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN;
 510        data->enable &= ~TCS3472_ENABLE_AIEN;
 511        ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
 512                data->enable);
 513        if (ret < 0)
 514                return ret;
 515
 516        ret = iio_triggered_buffer_setup(indio_dev, NULL,
 517                tcs3472_trigger_handler, NULL);
 518        if (ret < 0)
 519                return ret;
 520
 521        if (client->irq) {
 522                ret = request_threaded_irq(client->irq, NULL,
 523                                           tcs3472_event_handler,
 524                                           IRQF_TRIGGER_FALLING | IRQF_SHARED |
 525                                           IRQF_ONESHOT,
 526                                           client->name, indio_dev);
 527                if (ret)
 528                        goto buffer_cleanup;
 529        }
 530
 531        ret = iio_device_register(indio_dev);
 532        if (ret < 0)
 533                goto free_irq;
 534
 535        return 0;
 536
 537free_irq:
 538        if (client->irq)
 539                free_irq(client->irq, indio_dev);
 540buffer_cleanup:
 541        iio_triggered_buffer_cleanup(indio_dev);
 542        return ret;
 543}
 544
 545static int tcs3472_powerdown(struct tcs3472_data *data)
 546{
 547        int ret;
 548        u8 enable_mask = TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON;
 549
 550        mutex_lock(&data->lock);
 551
 552        ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
 553                data->enable & ~enable_mask);
 554        if (!ret)
 555                data->enable &= ~enable_mask;
 556
 557        mutex_unlock(&data->lock);
 558
 559        return ret;
 560}
 561
 562static int tcs3472_remove(struct i2c_client *client)
 563{
 564        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 565
 566        iio_device_unregister(indio_dev);
 567        if (client->irq)
 568                free_irq(client->irq, indio_dev);
 569        iio_triggered_buffer_cleanup(indio_dev);
 570        tcs3472_powerdown(iio_priv(indio_dev));
 571
 572        return 0;
 573}
 574
 575#ifdef CONFIG_PM_SLEEP
 576static int tcs3472_suspend(struct device *dev)
 577{
 578        struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
 579                to_i2c_client(dev)));
 580        return tcs3472_powerdown(data);
 581}
 582
 583static int tcs3472_resume(struct device *dev)
 584{
 585        struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
 586                to_i2c_client(dev)));
 587        int ret;
 588        u8 enable_mask = TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON;
 589
 590        mutex_lock(&data->lock);
 591
 592        ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
 593                data->enable | enable_mask);
 594        if (!ret)
 595                data->enable |= enable_mask;
 596
 597        mutex_unlock(&data->lock);
 598
 599        return ret;
 600}
 601#endif
 602
 603static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume);
 604
 605static const struct i2c_device_id tcs3472_id[] = {
 606        { "tcs3472", 0 },
 607        { }
 608};
 609MODULE_DEVICE_TABLE(i2c, tcs3472_id);
 610
 611static struct i2c_driver tcs3472_driver = {
 612        .driver = {
 613                .name   = TCS3472_DRV_NAME,
 614                .pm     = &tcs3472_pm_ops,
 615        },
 616        .probe          = tcs3472_probe,
 617        .remove         = tcs3472_remove,
 618        .id_table       = tcs3472_id,
 619};
 620module_i2c_driver(tcs3472_driver);
 621
 622MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
 623MODULE_DESCRIPTION("TCS3472 color light sensors driver");
 624MODULE_LICENSE("GPL");
 625