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