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 .pm = BH1750_PM_OPS, 323 }, 324 .probe = bh1750_probe, 325 .remove = bh1750_remove, 326 .id_table = bh1750_id, 327 328}; 329module_i2c_driver(bh1750_driver); 330 331MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>"); 332MODULE_DESCRIPTION("ROHM BH1710/BH1715/BH1721/BH1750/BH1751 als driver"); 333MODULE_LICENSE("GPL v2"); 334