1 /* 2 * CM3323 - Capella Color Light Sensor 3 * 4 * Copyright (c) 2015, Intel Corporation. 5 * 6 * This file is subject to the terms and conditions of version 2 of 7 * the GNU General Public License. See the file COPYING in the main 8 * directory of this archive for more details. 9 * 10 * IIO driver for CM3323 (7-bit I2C slave address 0x10) 11 * 12 * TODO: calibscale to correct the lens factor 13 */ 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/i2c.h> 17 #include <linux/mutex.h> 18 19 #include <linux/iio/iio.h> 20 #include <linux/iio/sysfs.h> 21 22 #define CM3323_DRV_NAME "cm3323" 23 24 #define CM3323_CMD_CONF 0x00 25 #define CM3323_CMD_RED_DATA 0x08 26 #define CM3323_CMD_GREEN_DATA 0x09 27 #define CM3323_CMD_BLUE_DATA 0x0A 28 #define CM3323_CMD_CLEAR_DATA 0x0B 29 30 #define CM3323_CONF_SD_BIT BIT(0) /* sensor disable */ 31 #define CM3323_CONF_AF_BIT BIT(1) /* auto/manual force mode */ 32 #define CM3323_CONF_IT_MASK (BIT(4) | BIT(5) | BIT(6)) 33 #define CM3323_CONF_IT_SHIFT 4 34 35 #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28" 36 37 static const struct { 38 int val; 39 int val2; 40 } cm3323_int_time[] = { 41 {0, 40000}, /* 40 ms */ 42 {0, 80000}, /* 80 ms */ 43 {0, 160000}, /* 160 ms */ 44 {0, 320000}, /* 320 ms */ 45 {0, 640000}, /* 640 ms */ 46 {1, 280000}, /* 1280 ms */ 47 }; 48 49 struct cm3323_data { 50 struct i2c_client *client; 51 u16 reg_conf; 52 struct mutex mutex; 53 }; 54 55 #define CM3323_COLOR_CHANNEL(_color, _addr) { \ 56 .type = IIO_INTENSITY, \ 57 .modified = 1, \ 58 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 59 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), \ 60 .channel2 = IIO_MOD_LIGHT_##_color, \ 61 .address = _addr, \ 62 } 63 64 static const struct iio_chan_spec cm3323_channels[] = { 65 CM3323_COLOR_CHANNEL(RED, CM3323_CMD_RED_DATA), 66 CM3323_COLOR_CHANNEL(GREEN, CM3323_CMD_GREEN_DATA), 67 CM3323_COLOR_CHANNEL(BLUE, CM3323_CMD_BLUE_DATA), 68 CM3323_COLOR_CHANNEL(CLEAR, CM3323_CMD_CLEAR_DATA), 69 }; 70 71 static IIO_CONST_ATTR_INT_TIME_AVAIL(CM3323_INT_TIME_AVAILABLE); 72 73 static struct attribute *cm3323_attributes[] = { 74 &iio_const_attr_integration_time_available.dev_attr.attr, 75 NULL 76 }; 77 78 static const struct attribute_group cm3323_attribute_group = { 79 .attrs = cm3323_attributes, 80 }; 81 82 static int cm3323_init(struct iio_dev *indio_dev) 83 { 84 int ret; 85 struct cm3323_data *data = iio_priv(indio_dev); 86 87 ret = i2c_smbus_read_word_data(data->client, CM3323_CMD_CONF); 88 if (ret < 0) { 89 dev_err(&data->client->dev, "Error reading reg_conf\n"); 90 return ret; 91 } 92 93 /* enable sensor and set auto force mode */ 94 ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT); 95 96 ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret); 97 if (ret < 0) { 98 dev_err(&data->client->dev, "Error writing reg_conf\n"); 99 return ret; 100 } 101 102 data->reg_conf = ret; 103 104 return 0; 105 } 106 107 static void cm3323_disable(struct iio_dev *indio_dev) 108 { 109 int ret; 110 struct cm3323_data *data = iio_priv(indio_dev); 111 112 ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, 113 CM3323_CONF_SD_BIT); 114 if (ret < 0) 115 dev_err(&data->client->dev, "Error writing reg_conf\n"); 116 } 117 118 static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2) 119 { 120 int i, ret; 121 u16 reg_conf; 122 123 for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) { 124 if (val == cm3323_int_time[i].val && 125 val2 == cm3323_int_time[i].val2) { 126 reg_conf = data->reg_conf; 127 reg_conf |= i << CM3323_CONF_IT_SHIFT; 128 129 ret = i2c_smbus_write_word_data(data->client, 130 CM3323_CMD_CONF, 131 reg_conf); 132 if (ret < 0) 133 return ret; 134 135 data->reg_conf = reg_conf; 136 return 0; 137 } 138 } 139 return -EINVAL; 140 } 141 142 static int cm3323_get_it_bits(struct cm3323_data *data) 143 { 144 int bits; 145 146 bits = (data->reg_conf & CM3323_CONF_IT_MASK) >> 147 CM3323_CONF_IT_SHIFT; 148 149 if (bits >= ARRAY_SIZE(cm3323_int_time)) 150 return -EINVAL; 151 return bits; 152 } 153 154 static int cm3323_read_raw(struct iio_dev *indio_dev, 155 struct iio_chan_spec const *chan, int *val, 156 int *val2, long mask) 157 { 158 int i, ret; 159 struct cm3323_data *data = iio_priv(indio_dev); 160 161 switch (mask) { 162 case IIO_CHAN_INFO_RAW: 163 mutex_lock(&data->mutex); 164 ret = i2c_smbus_read_word_data(data->client, chan->address); 165 if (ret < 0) { 166 mutex_unlock(&data->mutex); 167 return ret; 168 } 169 *val = ret; 170 mutex_unlock(&data->mutex); 171 172 return IIO_VAL_INT; 173 case IIO_CHAN_INFO_INT_TIME: 174 mutex_lock(&data->mutex); 175 i = cm3323_get_it_bits(data); 176 if (i < 0) { 177 mutex_unlock(&data->mutex); 178 return -EINVAL; 179 } 180 181 *val = cm3323_int_time[i].val; 182 *val2 = cm3323_int_time[i].val2; 183 mutex_unlock(&data->mutex); 184 185 return IIO_VAL_INT_PLUS_MICRO; 186 default: 187 return -EINVAL; 188 } 189 } 190 191 static int cm3323_write_raw(struct iio_dev *indio_dev, 192 struct iio_chan_spec const *chan, int val, 193 int val2, long mask) 194 { 195 struct cm3323_data *data = iio_priv(indio_dev); 196 int ret; 197 198 switch (mask) { 199 case IIO_CHAN_INFO_INT_TIME: 200 mutex_lock(&data->mutex); 201 ret = cm3323_set_it_bits(data, val, val2); 202 mutex_unlock(&data->mutex); 203 204 return ret; 205 default: 206 return -EINVAL; 207 } 208 } 209 210 static const struct iio_info cm3323_info = { 211 .driver_module = THIS_MODULE, 212 .read_raw = cm3323_read_raw, 213 .write_raw = cm3323_write_raw, 214 .attrs = &cm3323_attribute_group, 215 }; 216 217 static int cm3323_probe(struct i2c_client *client, 218 const struct i2c_device_id *id) 219 { 220 struct cm3323_data *data; 221 struct iio_dev *indio_dev; 222 int ret; 223 224 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 225 if (!indio_dev) 226 return -ENOMEM; 227 228 data = iio_priv(indio_dev); 229 i2c_set_clientdata(client, indio_dev); 230 data->client = client; 231 232 mutex_init(&data->mutex); 233 234 indio_dev->dev.parent = &client->dev; 235 indio_dev->info = &cm3323_info; 236 indio_dev->name = CM3323_DRV_NAME; 237 indio_dev->channels = cm3323_channels; 238 indio_dev->num_channels = ARRAY_SIZE(cm3323_channels); 239 indio_dev->modes = INDIO_DIRECT_MODE; 240 241 ret = cm3323_init(indio_dev); 242 if (ret < 0) { 243 dev_err(&client->dev, "cm3323 chip init failed\n"); 244 return ret; 245 } 246 ret = iio_device_register(indio_dev); 247 if (ret < 0) { 248 dev_err(&client->dev, "failed to register iio dev\n"); 249 goto err_init; 250 } 251 return 0; 252 err_init: 253 cm3323_disable(indio_dev); 254 return ret; 255 } 256 257 static int cm3323_remove(struct i2c_client *client) 258 { 259 struct iio_dev *indio_dev = i2c_get_clientdata(client); 260 261 iio_device_unregister(indio_dev); 262 cm3323_disable(indio_dev); 263 264 return 0; 265 } 266 267 static const struct i2c_device_id cm3323_id[] = { 268 {"cm3323", 0}, 269 {} 270 }; 271 MODULE_DEVICE_TABLE(i2c, cm3323_id); 272 273 static struct i2c_driver cm3323_driver = { 274 .driver = { 275 .name = CM3323_DRV_NAME, 276 }, 277 .probe = cm3323_probe, 278 .remove = cm3323_remove, 279 .id_table = cm3323_id, 280 }; 281 282 module_i2c_driver(cm3323_driver); 283 284 MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>"); 285 MODULE_DESCRIPTION("Capella CM3323 Color Light Sensor driver"); 286 MODULE_LICENSE("GPL v2"); 287