1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * tsl4531.c - Support for TAOS TSL4531 ambient light sensor 4 * 5 * Copyright 2013 Peter Meerwald <pmeerw@pmeerw.net> 6 * 7 * IIO driver for the TSL4531x family 8 * TSL45311/TSL45313: 7-bit I2C slave address 0x39 9 * TSL45315/TSL45317: 7-bit I2C slave address 0x29 10 * 11 * TODO: single cycle measurement 12 */ 13 14 #include <linux/module.h> 15 #include <linux/i2c.h> 16 #include <linux/err.h> 17 #include <linux/delay.h> 18 19 #include <linux/iio/iio.h> 20 #include <linux/iio/sysfs.h> 21 22 #define TSL4531_DRV_NAME "tsl4531" 23 24 #define TSL4531_COMMAND BIT(7) 25 26 #define TSL4531_CONTROL (TSL4531_COMMAND | 0x00) 27 #define TSL4531_CONFIG (TSL4531_COMMAND | 0x01) 28 #define TSL4531_DATA (TSL4531_COMMAND | 0x04) 29 #define TSL4531_ID (TSL4531_COMMAND | 0x0a) 30 31 /* operating modes in control register */ 32 #define TSL4531_MODE_POWERDOWN 0x00 33 #define TSL4531_MODE_SINGLE_ADC 0x02 34 #define TSL4531_MODE_NORMAL 0x03 35 36 /* integration time control in config register */ 37 #define TSL4531_TCNTRL_400MS 0x00 38 #define TSL4531_TCNTRL_200MS 0x01 39 #define TSL4531_TCNTRL_100MS 0x02 40 41 /* part number in id register */ 42 #define TSL45311_ID 0x8 43 #define TSL45313_ID 0x9 44 #define TSL45315_ID 0xa 45 #define TSL45317_ID 0xb 46 #define TSL4531_ID_SHIFT 4 47 48 struct tsl4531_data { 49 struct i2c_client *client; 50 struct mutex lock; 51 int int_time; 52 }; 53 54 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.2 0.4"); 55 56 static struct attribute *tsl4531_attributes[] = { 57 &iio_const_attr_integration_time_available.dev_attr.attr, 58 NULL 59 }; 60 61 static const struct attribute_group tsl4531_attribute_group = { 62 .attrs = tsl4531_attributes, 63 }; 64 65 static const struct iio_chan_spec tsl4531_channels[] = { 66 { 67 .type = IIO_LIGHT, 68 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 69 BIT(IIO_CHAN_INFO_SCALE) | 70 BIT(IIO_CHAN_INFO_INT_TIME) 71 } 72 }; 73 74 static int tsl4531_read_raw(struct iio_dev *indio_dev, 75 struct iio_chan_spec const *chan, 76 int *val, int *val2, long mask) 77 { 78 struct tsl4531_data *data = iio_priv(indio_dev); 79 int ret; 80 81 switch (mask) { 82 case IIO_CHAN_INFO_RAW: 83 ret = i2c_smbus_read_word_data(data->client, 84 TSL4531_DATA); 85 if (ret < 0) 86 return ret; 87 *val = ret; 88 return IIO_VAL_INT; 89 case IIO_CHAN_INFO_SCALE: 90 /* 0.. 1x, 1 .. 2x, 2 .. 4x */ 91 *val = 1 << data->int_time; 92 return IIO_VAL_INT; 93 case IIO_CHAN_INFO_INT_TIME: 94 if (data->int_time == 0) 95 *val2 = 400000; 96 else if (data->int_time == 1) 97 *val2 = 200000; 98 else if (data->int_time == 2) 99 *val2 = 100000; 100 else 101 return -EINVAL; 102 *val = 0; 103 return IIO_VAL_INT_PLUS_MICRO; 104 default: 105 return -EINVAL; 106 } 107 } 108 109 static int tsl4531_write_raw(struct iio_dev *indio_dev, 110 struct iio_chan_spec const *chan, 111 int val, int val2, long mask) 112 { 113 struct tsl4531_data *data = iio_priv(indio_dev); 114 int int_time, ret; 115 116 switch (mask) { 117 case IIO_CHAN_INFO_INT_TIME: 118 if (val != 0) 119 return -EINVAL; 120 if (val2 == 400000) 121 int_time = 0; 122 else if (val2 == 200000) 123 int_time = 1; 124 else if (val2 == 100000) 125 int_time = 2; 126 else 127 return -EINVAL; 128 mutex_lock(&data->lock); 129 ret = i2c_smbus_write_byte_data(data->client, 130 TSL4531_CONFIG, int_time); 131 if (ret >= 0) 132 data->int_time = int_time; 133 mutex_unlock(&data->lock); 134 return ret; 135 default: 136 return -EINVAL; 137 } 138 } 139 140 static const struct iio_info tsl4531_info = { 141 .read_raw = tsl4531_read_raw, 142 .write_raw = tsl4531_write_raw, 143 .attrs = &tsl4531_attribute_group, 144 }; 145 146 static int tsl4531_check_id(struct i2c_client *client) 147 { 148 int ret = i2c_smbus_read_byte_data(client, TSL4531_ID); 149 if (ret < 0) 150 return ret; 151 152 switch (ret >> TSL4531_ID_SHIFT) { 153 case TSL45311_ID: 154 case TSL45313_ID: 155 case TSL45315_ID: 156 case TSL45317_ID: 157 return 0; 158 default: 159 return -ENODEV; 160 } 161 } 162 163 static int tsl4531_probe(struct i2c_client *client, 164 const struct i2c_device_id *id) 165 { 166 struct tsl4531_data *data; 167 struct iio_dev *indio_dev; 168 int ret; 169 170 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 171 if (!indio_dev) 172 return -ENOMEM; 173 174 data = iio_priv(indio_dev); 175 i2c_set_clientdata(client, indio_dev); 176 data->client = client; 177 mutex_init(&data->lock); 178 179 ret = tsl4531_check_id(client); 180 if (ret) { 181 dev_err(&client->dev, "no TSL4531 sensor\n"); 182 return ret; 183 } 184 185 ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONTROL, 186 TSL4531_MODE_NORMAL); 187 if (ret < 0) 188 return ret; 189 190 ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONFIG, 191 TSL4531_TCNTRL_400MS); 192 if (ret < 0) 193 return ret; 194 195 indio_dev->info = &tsl4531_info; 196 indio_dev->channels = tsl4531_channels; 197 indio_dev->num_channels = ARRAY_SIZE(tsl4531_channels); 198 indio_dev->name = TSL4531_DRV_NAME; 199 indio_dev->modes = INDIO_DIRECT_MODE; 200 201 return iio_device_register(indio_dev); 202 } 203 204 static int tsl4531_powerdown(struct i2c_client *client) 205 { 206 return i2c_smbus_write_byte_data(client, TSL4531_CONTROL, 207 TSL4531_MODE_POWERDOWN); 208 } 209 210 static void tsl4531_remove(struct i2c_client *client) 211 { 212 iio_device_unregister(i2c_get_clientdata(client)); 213 tsl4531_powerdown(client); 214 } 215 216 static int tsl4531_suspend(struct device *dev) 217 { 218 return tsl4531_powerdown(to_i2c_client(dev)); 219 } 220 221 static int tsl4531_resume(struct device *dev) 222 { 223 return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL, 224 TSL4531_MODE_NORMAL); 225 } 226 227 static DEFINE_SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, 228 tsl4531_resume); 229 230 static const struct i2c_device_id tsl4531_id[] = { 231 { "tsl4531", 0 }, 232 { } 233 }; 234 MODULE_DEVICE_TABLE(i2c, tsl4531_id); 235 236 static struct i2c_driver tsl4531_driver = { 237 .driver = { 238 .name = TSL4531_DRV_NAME, 239 .pm = pm_sleep_ptr(&tsl4531_pm_ops), 240 }, 241 .probe = tsl4531_probe, 242 .remove = tsl4531_remove, 243 .id_table = tsl4531_id, 244 }; 245 246 module_i2c_driver(tsl4531_driver); 247 248 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 249 MODULE_DESCRIPTION("TAOS TSL4531 ambient light sensors driver"); 250 MODULE_LICENSE("GPL"); 251