1 /* 2 * ROHM 1780GLI Ambient Light Sensor Driver 3 * 4 * Copyright (C) 2016 Linaro Ltd. 5 * Author: Linus Walleij <linus.walleij@linaro.org> 6 * Loosely based on the previous BH1780 ALS misc driver 7 * Copyright (C) 2010 Texas Instruments 8 * Author: Hemanth V <hemanthv@ti.com> 9 */ 10 #include <linux/i2c.h> 11 #include <linux/slab.h> 12 #include <linux/platform_device.h> 13 #include <linux/delay.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/iio/iio.h> 18 #include <linux/iio/sysfs.h> 19 #include <linux/bitops.h> 20 21 #define BH1780_CMD_BIT BIT(7) 22 #define BH1780_REG_CONTROL 0x00 23 #define BH1780_REG_PARTID 0x0A 24 #define BH1780_REG_MANFID 0x0B 25 #define BH1780_REG_DLOW 0x0C 26 #define BH1780_REG_DHIGH 0x0D 27 28 #define BH1780_REVMASK GENMASK(3,0) 29 #define BH1780_POWMASK GENMASK(1,0) 30 #define BH1780_POFF (0x0) 31 #define BH1780_PON (0x3) 32 33 /* power on settling time in ms */ 34 #define BH1780_PON_DELAY 2 35 /* max time before value available in ms */ 36 #define BH1780_INTERVAL 250 37 38 struct bh1780_data { 39 struct i2c_client *client; 40 }; 41 42 static int bh1780_write(struct bh1780_data *bh1780, u8 reg, u8 val) 43 { 44 int ret = i2c_smbus_write_byte_data(bh1780->client, 45 BH1780_CMD_BIT | reg, 46 val); 47 if (ret < 0) 48 dev_err(&bh1780->client->dev, 49 "i2c_smbus_write_byte_data failed error " 50 "%d, register %01x\n", 51 ret, reg); 52 return ret; 53 } 54 55 static int bh1780_read(struct bh1780_data *bh1780, u8 reg) 56 { 57 int ret = i2c_smbus_read_byte_data(bh1780->client, 58 BH1780_CMD_BIT | reg); 59 if (ret < 0) 60 dev_err(&bh1780->client->dev, 61 "i2c_smbus_read_byte_data failed error " 62 "%d, register %01x\n", 63 ret, reg); 64 return ret; 65 } 66 67 static int bh1780_read_word(struct bh1780_data *bh1780, u8 reg) 68 { 69 int ret = i2c_smbus_read_word_data(bh1780->client, 70 BH1780_CMD_BIT | reg); 71 if (ret < 0) 72 dev_err(&bh1780->client->dev, 73 "i2c_smbus_read_word_data failed error " 74 "%d, register %01x\n", 75 ret, reg); 76 return ret; 77 } 78 79 static int bh1780_debugfs_reg_access(struct iio_dev *indio_dev, 80 unsigned int reg, unsigned int writeval, 81 unsigned int *readval) 82 { 83 struct bh1780_data *bh1780 = iio_priv(indio_dev); 84 int ret; 85 86 if (!readval) 87 return bh1780_write(bh1780, (u8)reg, (u8)writeval); 88 89 ret = bh1780_read(bh1780, (u8)reg); 90 if (ret < 0) 91 return ret; 92 93 *readval = ret; 94 95 return 0; 96 } 97 98 static int bh1780_read_raw(struct iio_dev *indio_dev, 99 struct iio_chan_spec const *chan, 100 int *val, int *val2, long mask) 101 { 102 struct bh1780_data *bh1780 = iio_priv(indio_dev); 103 int value; 104 105 switch (mask) { 106 case IIO_CHAN_INFO_RAW: 107 switch (chan->type) { 108 case IIO_LIGHT: 109 pm_runtime_get_sync(&bh1780->client->dev); 110 value = bh1780_read_word(bh1780, BH1780_REG_DLOW); 111 if (value < 0) 112 return value; 113 pm_runtime_mark_last_busy(&bh1780->client->dev); 114 pm_runtime_put_autosuspend(&bh1780->client->dev); 115 *val = value; 116 117 return IIO_VAL_INT; 118 default: 119 return -EINVAL; 120 } 121 case IIO_CHAN_INFO_INT_TIME: 122 *val = 0; 123 *val2 = BH1780_INTERVAL * 1000; 124 return IIO_VAL_INT_PLUS_MICRO; 125 default: 126 return -EINVAL; 127 } 128 } 129 130 static const struct iio_info bh1780_info = { 131 .driver_module = THIS_MODULE, 132 .read_raw = bh1780_read_raw, 133 .debugfs_reg_access = bh1780_debugfs_reg_access, 134 }; 135 136 static const struct iio_chan_spec bh1780_channels[] = { 137 { 138 .type = IIO_LIGHT, 139 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 140 BIT(IIO_CHAN_INFO_INT_TIME) 141 } 142 }; 143 144 static int bh1780_probe(struct i2c_client *client, 145 const struct i2c_device_id *id) 146 { 147 int ret; 148 struct bh1780_data *bh1780; 149 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 150 struct iio_dev *indio_dev; 151 152 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) 153 return -EIO; 154 155 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*bh1780)); 156 if (!indio_dev) 157 return -ENOMEM; 158 159 bh1780 = iio_priv(indio_dev); 160 bh1780->client = client; 161 i2c_set_clientdata(client, indio_dev); 162 163 /* Power up the device */ 164 ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON); 165 if (ret < 0) 166 return ret; 167 msleep(BH1780_PON_DELAY); 168 pm_runtime_get_noresume(&client->dev); 169 pm_runtime_set_active(&client->dev); 170 pm_runtime_enable(&client->dev); 171 172 ret = bh1780_read(bh1780, BH1780_REG_PARTID); 173 if (ret < 0) 174 goto out_disable_pm; 175 dev_info(&client->dev, 176 "Ambient Light Sensor, Rev : %lu\n", 177 (ret & BH1780_REVMASK)); 178 179 /* 180 * As the device takes 250 ms to even come up with a fresh 181 * measurement after power-on, do not shut it down unnecessarily. 182 * Set autosuspend to a five seconds. 183 */ 184 pm_runtime_set_autosuspend_delay(&client->dev, 5000); 185 pm_runtime_use_autosuspend(&client->dev); 186 pm_runtime_put(&client->dev); 187 188 indio_dev->dev.parent = &client->dev; 189 indio_dev->info = &bh1780_info; 190 indio_dev->name = "bh1780"; 191 indio_dev->channels = bh1780_channels; 192 indio_dev->num_channels = ARRAY_SIZE(bh1780_channels); 193 indio_dev->modes = INDIO_DIRECT_MODE; 194 195 ret = iio_device_register(indio_dev); 196 if (ret) 197 goto out_disable_pm; 198 return 0; 199 200 out_disable_pm: 201 pm_runtime_put_noidle(&client->dev); 202 pm_runtime_disable(&client->dev); 203 return ret; 204 } 205 206 static int bh1780_remove(struct i2c_client *client) 207 { 208 struct iio_dev *indio_dev = i2c_get_clientdata(client); 209 struct bh1780_data *bh1780 = iio_priv(indio_dev); 210 int ret; 211 212 iio_device_unregister(indio_dev); 213 pm_runtime_get_sync(&client->dev); 214 pm_runtime_put_noidle(&client->dev); 215 pm_runtime_disable(&client->dev); 216 ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF); 217 if (ret < 0) { 218 dev_err(&client->dev, "failed to power off\n"); 219 return ret; 220 } 221 222 return 0; 223 } 224 225 #ifdef CONFIG_PM 226 static int bh1780_runtime_suspend(struct device *dev) 227 { 228 struct i2c_client *client = to_i2c_client(dev); 229 struct iio_dev *indio_dev = i2c_get_clientdata(client); 230 struct bh1780_data *bh1780 = iio_priv(indio_dev); 231 int ret; 232 233 ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_POFF); 234 if (ret < 0) { 235 dev_err(dev, "failed to runtime suspend\n"); 236 return ret; 237 } 238 239 return 0; 240 } 241 242 static int bh1780_runtime_resume(struct device *dev) 243 { 244 struct i2c_client *client = to_i2c_client(dev); 245 struct iio_dev *indio_dev = i2c_get_clientdata(client); 246 struct bh1780_data *bh1780 = iio_priv(indio_dev); 247 int ret; 248 249 ret = bh1780_write(bh1780, BH1780_REG_CONTROL, BH1780_PON); 250 if (ret < 0) { 251 dev_err(dev, "failed to runtime resume\n"); 252 return ret; 253 } 254 255 /* Wait for power on, then for a value to be available */ 256 msleep(BH1780_PON_DELAY + BH1780_INTERVAL); 257 258 return 0; 259 } 260 #endif /* CONFIG_PM */ 261 262 static const struct dev_pm_ops bh1780_dev_pm_ops = { 263 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 264 pm_runtime_force_resume) 265 SET_RUNTIME_PM_OPS(bh1780_runtime_suspend, 266 bh1780_runtime_resume, NULL) 267 }; 268 269 static const struct i2c_device_id bh1780_id[] = { 270 { "bh1780", 0 }, 271 { }, 272 }; 273 274 MODULE_DEVICE_TABLE(i2c, bh1780_id); 275 276 #ifdef CONFIG_OF 277 static const struct of_device_id of_bh1780_match[] = { 278 { .compatible = "rohm,bh1780gli", }, 279 {}, 280 }; 281 MODULE_DEVICE_TABLE(of, of_bh1780_match); 282 #endif 283 284 static struct i2c_driver bh1780_driver = { 285 .probe = bh1780_probe, 286 .remove = bh1780_remove, 287 .id_table = bh1780_id, 288 .driver = { 289 .name = "bh1780", 290 .pm = &bh1780_dev_pm_ops, 291 .of_match_table = of_match_ptr(of_bh1780_match), 292 }, 293 }; 294 295 module_i2c_driver(bh1780_driver); 296 297 MODULE_DESCRIPTION("ROHM BH1780GLI Ambient Light Sensor Driver"); 298 MODULE_LICENSE("GPL"); 299 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 300