Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * ROHM BH1710/BH1715/BH1721/BH1750/BH1751 ambient light sensor driver
0004  *
0005  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
0006  *
0007  * Data sheets:
0008  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1710fvc-e.pdf
0009  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1715fvc-e.pdf
0010  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf
0011  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
0012  *  http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1751fvi-e.pdf
0013  *
0014  * 7-bit I2C slave addresses:
0015  *  0x23 (ADDR pin low)
0016  *  0x5C (ADDR pin high)
0017  *
0018  */
0019 
0020 #include <linux/delay.h>
0021 #include <linux/i2c.h>
0022 #include <linux/iio/iio.h>
0023 #include <linux/iio/sysfs.h>
0024 #include <linux/module.h>
0025 
0026 #define BH1750_POWER_DOWN       0x00
0027 #define BH1750_ONE_TIME_H_RES_MODE  0x20 /* auto-mode for BH1721 */
0028 #define BH1750_CHANGE_INT_TIME_H_BIT    0x40
0029 #define BH1750_CHANGE_INT_TIME_L_BIT    0x60
0030 
0031 enum {
0032     BH1710,
0033     BH1721,
0034     BH1750,
0035 };
0036 
0037 struct bh1750_chip_info;
0038 struct bh1750_data {
0039     struct i2c_client *client;
0040     struct mutex lock;
0041     const struct bh1750_chip_info *chip_info;
0042     u16 mtreg;
0043 };
0044 
0045 struct bh1750_chip_info {
0046     u16 mtreg_min;
0047     u16 mtreg_max;
0048     u16 mtreg_default;
0049     int mtreg_to_usec;
0050     int mtreg_to_scale;
0051 
0052     /*
0053      * For BH1710/BH1721 all possible integration time values won't fit
0054      * into one page so displaying is limited to every second one.
0055      * Note, that user can still write proper values which were not
0056      * listed.
0057      */
0058     int inc;
0059 
0060     u16 int_time_low_mask;
0061     u16 int_time_high_mask;
0062 };
0063 
0064 static const struct bh1750_chip_info bh1750_chip_info_tbl[] = {
0065     [BH1710] = { 140, 1022, 300, 400,  250000000, 2, 0x001F, 0x03E0 },
0066     [BH1721] = { 140, 1020, 300, 400,  250000000, 2, 0x0010, 0x03E0 },
0067     [BH1750] = { 31,  254,  69,  1740, 57500000,  1, 0x001F, 0x00E0 },
0068 };
0069 
0070 static int bh1750_change_int_time(struct bh1750_data *data, int usec)
0071 {
0072     int ret;
0073     u16 val;
0074     u8 regval;
0075     const struct bh1750_chip_info *chip_info = data->chip_info;
0076 
0077     if ((usec % chip_info->mtreg_to_usec) != 0)
0078         return -EINVAL;
0079 
0080     val = usec / chip_info->mtreg_to_usec;
0081     if (val < chip_info->mtreg_min || val > chip_info->mtreg_max)
0082         return -EINVAL;
0083 
0084     ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
0085     if (ret < 0)
0086         return ret;
0087 
0088     regval = (val & chip_info->int_time_high_mask) >> 5;
0089     ret = i2c_smbus_write_byte(data->client,
0090                    BH1750_CHANGE_INT_TIME_H_BIT | regval);
0091     if (ret < 0)
0092         return ret;
0093 
0094     regval = val & chip_info->int_time_low_mask;
0095     ret = i2c_smbus_write_byte(data->client,
0096                    BH1750_CHANGE_INT_TIME_L_BIT | regval);
0097     if (ret < 0)
0098         return ret;
0099 
0100     data->mtreg = val;
0101 
0102     return 0;
0103 }
0104 
0105 static int bh1750_read(struct bh1750_data *data, int *val)
0106 {
0107     int ret;
0108     __be16 result;
0109     const struct bh1750_chip_info *chip_info = data->chip_info;
0110     unsigned long delay = chip_info->mtreg_to_usec * data->mtreg;
0111 
0112     /*
0113      * BH1721 will enter continuous mode on receiving this command.
0114      * Note, that this eliminates need for bh1750_resume().
0115      */
0116     ret = i2c_smbus_write_byte(data->client, BH1750_ONE_TIME_H_RES_MODE);
0117     if (ret < 0)
0118         return ret;
0119 
0120     usleep_range(delay + 15000, delay + 40000);
0121 
0122     ret = i2c_master_recv(data->client, (char *)&result, 2);
0123     if (ret < 0)
0124         return ret;
0125 
0126     *val = be16_to_cpu(result);
0127 
0128     return 0;
0129 }
0130 
0131 static int bh1750_read_raw(struct iio_dev *indio_dev,
0132                struct iio_chan_spec const *chan,
0133                int *val, int *val2, long mask)
0134 {
0135     int ret, tmp;
0136     struct bh1750_data *data = iio_priv(indio_dev);
0137     const struct bh1750_chip_info *chip_info = data->chip_info;
0138 
0139     switch (mask) {
0140     case IIO_CHAN_INFO_RAW:
0141         switch (chan->type) {
0142         case IIO_LIGHT:
0143             mutex_lock(&data->lock);
0144             ret = bh1750_read(data, val);
0145             mutex_unlock(&data->lock);
0146             if (ret < 0)
0147                 return ret;
0148 
0149             return IIO_VAL_INT;
0150         default:
0151             return -EINVAL;
0152         }
0153     case IIO_CHAN_INFO_SCALE:
0154         tmp = chip_info->mtreg_to_scale / data->mtreg;
0155         *val = tmp / 1000000;
0156         *val2 = tmp % 1000000;
0157         return IIO_VAL_INT_PLUS_MICRO;
0158     case IIO_CHAN_INFO_INT_TIME:
0159         *val = 0;
0160         *val2 = chip_info->mtreg_to_usec * data->mtreg;
0161         return IIO_VAL_INT_PLUS_MICRO;
0162     default:
0163         return -EINVAL;
0164     }
0165 }
0166 
0167 static int bh1750_write_raw(struct iio_dev *indio_dev,
0168                 struct iio_chan_spec const *chan,
0169                 int val, int val2, long mask)
0170 {
0171     int ret;
0172     struct bh1750_data *data = iio_priv(indio_dev);
0173 
0174     switch (mask) {
0175     case IIO_CHAN_INFO_INT_TIME:
0176         if (val != 0)
0177             return -EINVAL;
0178 
0179         mutex_lock(&data->lock);
0180         ret = bh1750_change_int_time(data, val2);
0181         mutex_unlock(&data->lock);
0182         return ret;
0183     default:
0184         return -EINVAL;
0185     }
0186 }
0187 
0188 static ssize_t bh1750_show_int_time_available(struct device *dev,
0189         struct device_attribute *attr, char *buf)
0190 {
0191     int i;
0192     size_t len = 0;
0193     struct bh1750_data *data = iio_priv(dev_to_iio_dev(dev));
0194     const struct bh1750_chip_info *chip_info = data->chip_info;
0195 
0196     for (i = chip_info->mtreg_min; i <= chip_info->mtreg_max; i += chip_info->inc)
0197         len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
0198                  chip_info->mtreg_to_usec * i);
0199 
0200     buf[len - 1] = '\n';
0201 
0202     return len;
0203 }
0204 
0205 static IIO_DEV_ATTR_INT_TIME_AVAIL(bh1750_show_int_time_available);
0206 
0207 static struct attribute *bh1750_attributes[] = {
0208     &iio_dev_attr_integration_time_available.dev_attr.attr,
0209     NULL,
0210 };
0211 
0212 static const struct attribute_group bh1750_attribute_group = {
0213     .attrs = bh1750_attributes,
0214 };
0215 
0216 static const struct iio_info bh1750_info = {
0217     .attrs = &bh1750_attribute_group,
0218     .read_raw = bh1750_read_raw,
0219     .write_raw = bh1750_write_raw,
0220 };
0221 
0222 static const struct iio_chan_spec bh1750_channels[] = {
0223     {
0224         .type = IIO_LIGHT,
0225         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0226                       BIT(IIO_CHAN_INFO_SCALE) |
0227                       BIT(IIO_CHAN_INFO_INT_TIME)
0228     }
0229 };
0230 
0231 static int bh1750_probe(struct i2c_client *client,
0232             const struct i2c_device_id *id)
0233 {
0234     int ret, usec;
0235     struct bh1750_data *data;
0236     struct iio_dev *indio_dev;
0237 
0238     if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
0239                 I2C_FUNC_SMBUS_WRITE_BYTE))
0240         return -EOPNOTSUPP;
0241 
0242     indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0243     if (!indio_dev)
0244         return -ENOMEM;
0245 
0246     data = iio_priv(indio_dev);
0247     i2c_set_clientdata(client, indio_dev);
0248     data->client = client;
0249     data->chip_info = &bh1750_chip_info_tbl[id->driver_data];
0250 
0251     usec = data->chip_info->mtreg_to_usec * data->chip_info->mtreg_default;
0252     ret = bh1750_change_int_time(data, usec);
0253     if (ret < 0)
0254         return ret;
0255 
0256     mutex_init(&data->lock);
0257     indio_dev->info = &bh1750_info;
0258     indio_dev->name = id->name;
0259     indio_dev->channels = bh1750_channels;
0260     indio_dev->num_channels = ARRAY_SIZE(bh1750_channels);
0261     indio_dev->modes = INDIO_DIRECT_MODE;
0262 
0263     return iio_device_register(indio_dev);
0264 }
0265 
0266 static int bh1750_remove(struct i2c_client *client)
0267 {
0268     struct iio_dev *indio_dev = i2c_get_clientdata(client);
0269     struct bh1750_data *data = iio_priv(indio_dev);
0270 
0271     iio_device_unregister(indio_dev);
0272 
0273     mutex_lock(&data->lock);
0274     i2c_smbus_write_byte(client, BH1750_POWER_DOWN);
0275     mutex_unlock(&data->lock);
0276 
0277     return 0;
0278 }
0279 
0280 static int bh1750_suspend(struct device *dev)
0281 {
0282     int ret;
0283     struct bh1750_data *data =
0284         iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
0285 
0286     /*
0287      * This is mainly for BH1721 which doesn't enter power down
0288      * mode automatically.
0289      */
0290     mutex_lock(&data->lock);
0291     ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
0292     mutex_unlock(&data->lock);
0293 
0294     return ret;
0295 }
0296 
0297 static DEFINE_SIMPLE_DEV_PM_OPS(bh1750_pm_ops, bh1750_suspend, NULL);
0298 
0299 static const struct i2c_device_id bh1750_id[] = {
0300     { "bh1710", BH1710 },
0301     { "bh1715", BH1750 },
0302     { "bh1721", BH1721 },
0303     { "bh1750", BH1750 },
0304     { "bh1751", BH1750 },
0305     { }
0306 };
0307 MODULE_DEVICE_TABLE(i2c, bh1750_id);
0308 
0309 static const struct of_device_id bh1750_of_match[] = {
0310     { .compatible = "rohm,bh1710", },
0311     { .compatible = "rohm,bh1715", },
0312     { .compatible = "rohm,bh1721", },
0313     { .compatible = "rohm,bh1750", },
0314     { .compatible = "rohm,bh1751", },
0315     { }
0316 };
0317 MODULE_DEVICE_TABLE(of, bh1750_of_match);
0318 
0319 static struct i2c_driver bh1750_driver = {
0320     .driver = {
0321         .name = "bh1750",
0322         .of_match_table = bh1750_of_match,
0323         .pm = pm_sleep_ptr(&bh1750_pm_ops),
0324     },
0325     .probe = bh1750_probe,
0326     .remove = bh1750_remove,
0327     .id_table = bh1750_id,
0328 
0329 };
0330 module_i2c_driver(bh1750_driver);
0331 
0332 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
0333 MODULE_DESCRIPTION("ROHM BH1710/BH1715/BH1721/BH1750/BH1751 als driver");
0334 MODULE_LICENSE("GPL v2");