linux/drivers/iio/light/bh1750.c
<<
>>
Prefs
   1/*
   2 * ROHM BH1710/BH1715/BH1721/BH1750/BH1751 ambient light sensor driver
   3 *
   4 * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * Data sheets:
  11 *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1710fvc-e.pdf
  12 *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1715fvc-e.pdf
  13 *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf
  14 *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
  15 *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1751fvi-e.pdf
  16 *
  17 * 7-bit I2C slave addresses:
  18 *  0x23 (ADDR pin low)
  19 *  0x5C (ADDR pin high)
  20 *
  21 */
  22
  23#include <linux/delay.h>
  24#include <linux/i2c.h>
  25#include <linux/iio/iio.h>
  26#include <linux/iio/sysfs.h>
  27#include <linux/module.h>
  28
  29#define BH1750_POWER_DOWN               0x00
  30#define BH1750_ONE_TIME_H_RES_MODE      0x20 /* auto-mode for BH1721 */
  31#define BH1750_CHANGE_INT_TIME_H_BIT    0x40
  32#define BH1750_CHANGE_INT_TIME_L_BIT    0x60
  33
  34enum {
  35        BH1710,
  36        BH1721,
  37        BH1750,
  38};
  39
  40struct bh1750_chip_info;
  41struct bh1750_data {
  42        struct i2c_client *client;
  43        struct mutex lock;
  44        const struct bh1750_chip_info *chip_info;
  45        u16 mtreg;
  46};
  47
  48struct bh1750_chip_info {
  49        u16 mtreg_min;
  50        u16 mtreg_max;
  51        u16 mtreg_default;
  52        int mtreg_to_usec;
  53        int mtreg_to_scale;
  54
  55        /*
  56         * For BH1710/BH1721 all possible integration time values won't fit
  57         * into one page so displaying is limited to every second one.
  58         * Note, that user can still write proper values which were not
  59         * listed.
  60         */
  61        int inc;
  62
  63        u16 int_time_low_mask;
  64        u16 int_time_high_mask;
  65}
  66
  67static const bh1750_chip_info_tbl[] = {
  68        [BH1710] = { 140, 1022, 300, 400,  250000000, 2, 0x001F, 0x03E0 },
  69        [BH1721] = { 140, 1020, 300, 400,  250000000, 2, 0x0010, 0x03E0 },
  70        [BH1750] = { 31,  254,  69,  1740, 57500000,  1, 0x001F, 0x00E0 },
  71};
  72
  73static int bh1750_change_int_time(struct bh1750_data *data, int usec)
  74{
  75        int ret;
  76        u16 val;
  77        u8 regval;
  78        const struct bh1750_chip_info *chip_info = data->chip_info;
  79
  80        if ((usec % chip_info->mtreg_to_usec) != 0)
  81                return -EINVAL;
  82
  83        val = usec / chip_info->mtreg_to_usec;
  84        if (val < chip_info->mtreg_min || val > chip_info->mtreg_max)
  85                return -EINVAL;
  86
  87        ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
  88        if (ret < 0)
  89                return ret;
  90
  91        regval = (val & chip_info->int_time_high_mask) >> 5;
  92        ret = i2c_smbus_write_byte(data->client,
  93                                   BH1750_CHANGE_INT_TIME_H_BIT | regval);
  94        if (ret < 0)
  95                return ret;
  96
  97        regval = val & chip_info->int_time_low_mask;
  98        ret = i2c_smbus_write_byte(data->client,
  99                                   BH1750_CHANGE_INT_TIME_L_BIT | regval);
 100        if (ret < 0)
 101                return ret;
 102
 103        data->mtreg = val;
 104
 105        return 0;
 106}
 107
 108static int bh1750_read(struct bh1750_data *data, int *val)
 109{
 110        int ret;
 111        __be16 result;
 112        const struct bh1750_chip_info *chip_info = data->chip_info;
 113        unsigned long delay = chip_info->mtreg_to_usec * data->mtreg;
 114
 115        /*
 116         * BH1721 will enter continuous mode on receiving this command.
 117         * Note, that this eliminates need for bh1750_resume().
 118         */
 119        ret = i2c_smbus_write_byte(data->client, BH1750_ONE_TIME_H_RES_MODE);
 120        if (ret < 0)
 121                return ret;
 122
 123        usleep_range(delay + 15000, delay + 40000);
 124
 125        ret = i2c_master_recv(data->client, (char *)&result, 2);
 126        if (ret < 0)
 127                return ret;
 128
 129        *val = be16_to_cpu(result);
 130
 131        return 0;
 132}
 133
 134static int bh1750_read_raw(struct iio_dev *indio_dev,
 135                           struct iio_chan_spec const *chan,
 136                           int *val, int *val2, long mask)
 137{
 138        int ret, tmp;
 139        struct bh1750_data *data = iio_priv(indio_dev);
 140        const struct bh1750_chip_info *chip_info = data->chip_info;
 141
 142        switch (mask) {
 143        case IIO_CHAN_INFO_RAW:
 144                switch (chan->type) {
 145                case IIO_LIGHT:
 146                        mutex_lock(&data->lock);
 147                        ret = bh1750_read(data, val);
 148                        mutex_unlock(&data->lock);
 149                        if (ret < 0)
 150                                return ret;
 151
 152                        return IIO_VAL_INT;
 153                default:
 154                        return -EINVAL;
 155                }
 156        case IIO_CHAN_INFO_SCALE:
 157                tmp = chip_info->mtreg_to_scale / data->mtreg;
 158                *val = tmp / 1000000;
 159                *val2 = tmp % 1000000;
 160                return IIO_VAL_INT_PLUS_MICRO;
 161        case IIO_CHAN_INFO_INT_TIME:
 162                *val = 0;
 163                *val2 = chip_info->mtreg_to_usec * data->mtreg;
 164                return IIO_VAL_INT_PLUS_MICRO;
 165        default:
 166                return -EINVAL;
 167        }
 168}
 169
 170static int bh1750_write_raw(struct iio_dev *indio_dev,
 171                            struct iio_chan_spec const *chan,
 172                            int val, int val2, long mask)
 173{
 174        int ret;
 175        struct bh1750_data *data = iio_priv(indio_dev);
 176
 177        switch (mask) {
 178        case IIO_CHAN_INFO_INT_TIME:
 179                if (val != 0)
 180                        return -EINVAL;
 181
 182                mutex_lock(&data->lock);
 183                ret = bh1750_change_int_time(data, val2);
 184                mutex_unlock(&data->lock);
 185                return ret;
 186        default:
 187                return -EINVAL;
 188        }
 189}
 190
 191static ssize_t bh1750_show_int_time_available(struct device *dev,
 192                struct device_attribute *attr, char *buf)
 193{
 194        int i;
 195        size_t len = 0;
 196        struct bh1750_data *data = iio_priv(dev_to_iio_dev(dev));
 197        const struct bh1750_chip_info *chip_info = data->chip_info;
 198
 199        for (i = chip_info->mtreg_min; i <= chip_info->mtreg_max; i += chip_info->inc)
 200                len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
 201                                 chip_info->mtreg_to_usec * i);
 202
 203        buf[len - 1] = '\n';
 204
 205        return len;
 206}
 207
 208static IIO_DEV_ATTR_INT_TIME_AVAIL(bh1750_show_int_time_available);
 209
 210static struct attribute *bh1750_attributes[] = {
 211        &iio_dev_attr_integration_time_available.dev_attr.attr,
 212        NULL,
 213};
 214
 215static struct attribute_group bh1750_attribute_group = {
 216        .attrs = bh1750_attributes,
 217};
 218
 219static const struct iio_info bh1750_info = {
 220        .driver_module = THIS_MODULE,
 221        .attrs = &bh1750_attribute_group,
 222        .read_raw = bh1750_read_raw,
 223        .write_raw = bh1750_write_raw,
 224};
 225
 226static const struct iio_chan_spec bh1750_channels[] = {
 227        {
 228                .type = IIO_LIGHT,
 229                .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
 230                                      BIT(IIO_CHAN_INFO_SCALE) |
 231                                      BIT(IIO_CHAN_INFO_INT_TIME)
 232        }
 233};
 234
 235static int bh1750_probe(struct i2c_client *client,
 236                        const struct i2c_device_id *id)
 237{
 238        int ret, usec;
 239        struct bh1750_data *data;
 240        struct iio_dev *indio_dev;
 241
 242        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
 243                                I2C_FUNC_SMBUS_WRITE_BYTE))
 244                return -ENODEV;
 245
 246        indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
 247        if (!indio_dev)
 248                return -ENOMEM;
 249
 250        data = iio_priv(indio_dev);
 251        i2c_set_clientdata(client, indio_dev);
 252        data->client = client;
 253        data->chip_info = &bh1750_chip_info_tbl[id->driver_data];
 254
 255        usec = data->chip_info->mtreg_to_usec * data->chip_info->mtreg_default;
 256        ret = bh1750_change_int_time(data, usec);
 257        if (ret < 0)
 258                return ret;
 259
 260        mutex_init(&data->lock);
 261        indio_dev->dev.parent = &client->dev;
 262        indio_dev->info = &bh1750_info;
 263        indio_dev->name = id->name;
 264        indio_dev->channels = bh1750_channels;
 265        indio_dev->num_channels = ARRAY_SIZE(bh1750_channels);
 266        indio_dev->modes = INDIO_DIRECT_MODE;
 267
 268        return iio_device_register(indio_dev);
 269}
 270
 271static int bh1750_remove(struct i2c_client *client)
 272{
 273        struct iio_dev *indio_dev = i2c_get_clientdata(client);
 274        struct bh1750_data *data = iio_priv(indio_dev);
 275
 276        iio_device_unregister(indio_dev);
 277
 278        mutex_lock(&data->lock);
 279        i2c_smbus_write_byte(client, BH1750_POWER_DOWN);
 280        mutex_unlock(&data->lock);
 281
 282        return 0;
 283}
 284
 285#ifdef CONFIG_PM_SLEEP
 286static int bh1750_suspend(struct device *dev)
 287{
 288        int ret;
 289        struct bh1750_data *data =
 290                iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
 291
 292        /*
 293         * This is mainly for BH1721 which doesn't enter power down
 294         * mode automatically.
 295         */
 296        mutex_lock(&data->lock);
 297        ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
 298        mutex_unlock(&data->lock);
 299
 300        return ret;
 301}
 302
 303static SIMPLE_DEV_PM_OPS(bh1750_pm_ops, bh1750_suspend, NULL);
 304#define BH1750_PM_OPS (&bh1750_pm_ops)
 305#else
 306#define BH1750_PM_OPS NULL
 307#endif
 308
 309static const struct i2c_device_id bh1750_id[] = {
 310        { "bh1710", BH1710 },
 311        { "bh1715", BH1750 },
 312        { "bh1721", BH1721 },
 313        { "bh1750", BH1750 },
 314        { "bh1751", BH1750 },
 315        { }
 316};
 317MODULE_DEVICE_TABLE(i2c, bh1750_id);
 318
 319static struct i2c_driver bh1750_driver = {
 320        .driver = {
 321                .name = "bh1750",
 322                .owner = THIS_MODULE,
 323                .pm = BH1750_PM_OPS,
 324        },
 325        .probe = bh1750_probe,
 326        .remove = bh1750_remove,
 327        .id_table = bh1750_id,
 328
 329};
 330module_i2c_driver(bh1750_driver);
 331
 332MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
 333MODULE_DESCRIPTION("ROHM BH1710/BH1715/BH1721/BH1750/BH1751 als driver");
 334MODULE_LICENSE("GPL v2");
 335