0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/i2c.h>
0014 #include <linux/mutex.h>
0015
0016 #include <linux/iio/iio.h>
0017 #include <linux/iio/sysfs.h>
0018
0019 #define CM3323_DRV_NAME "cm3323"
0020
0021 #define CM3323_CMD_CONF 0x00
0022 #define CM3323_CMD_RED_DATA 0x08
0023 #define CM3323_CMD_GREEN_DATA 0x09
0024 #define CM3323_CMD_BLUE_DATA 0x0A
0025 #define CM3323_CMD_CLEAR_DATA 0x0B
0026
0027 #define CM3323_CONF_SD_BIT BIT(0)
0028 #define CM3323_CONF_AF_BIT BIT(1)
0029 #define CM3323_CONF_IT_MASK GENMASK(6, 4)
0030 #define CM3323_CONF_IT_SHIFT 4
0031
0032 #define CM3323_INT_TIME_AVAILABLE "0.04 0.08 0.16 0.32 0.64 1.28"
0033
0034 static const struct {
0035 int val;
0036 int val2;
0037 } cm3323_int_time[] = {
0038 {0, 40000},
0039 {0, 80000},
0040 {0, 160000},
0041 {0, 320000},
0042 {0, 640000},
0043 {1, 280000},
0044 };
0045
0046 struct cm3323_data {
0047 struct i2c_client *client;
0048 u16 reg_conf;
0049 struct mutex mutex;
0050 };
0051
0052 #define CM3323_COLOR_CHANNEL(_color, _addr) { \
0053 .type = IIO_INTENSITY, \
0054 .modified = 1, \
0055 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0056 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME), \
0057 .channel2 = IIO_MOD_LIGHT_##_color, \
0058 .address = _addr, \
0059 }
0060
0061 static const struct iio_chan_spec cm3323_channels[] = {
0062 CM3323_COLOR_CHANNEL(RED, CM3323_CMD_RED_DATA),
0063 CM3323_COLOR_CHANNEL(GREEN, CM3323_CMD_GREEN_DATA),
0064 CM3323_COLOR_CHANNEL(BLUE, CM3323_CMD_BLUE_DATA),
0065 CM3323_COLOR_CHANNEL(CLEAR, CM3323_CMD_CLEAR_DATA),
0066 };
0067
0068 static IIO_CONST_ATTR_INT_TIME_AVAIL(CM3323_INT_TIME_AVAILABLE);
0069
0070 static struct attribute *cm3323_attributes[] = {
0071 &iio_const_attr_integration_time_available.dev_attr.attr,
0072 NULL
0073 };
0074
0075 static const struct attribute_group cm3323_attribute_group = {
0076 .attrs = cm3323_attributes,
0077 };
0078
0079 static int cm3323_init(struct iio_dev *indio_dev)
0080 {
0081 int ret;
0082 struct cm3323_data *data = iio_priv(indio_dev);
0083
0084 ret = i2c_smbus_read_word_data(data->client, CM3323_CMD_CONF);
0085 if (ret < 0) {
0086 dev_err(&data->client->dev, "Error reading reg_conf\n");
0087 return ret;
0088 }
0089
0090
0091 ret &= ~(CM3323_CONF_SD_BIT | CM3323_CONF_AF_BIT);
0092
0093 ret = i2c_smbus_write_word_data(data->client, CM3323_CMD_CONF, ret);
0094 if (ret < 0) {
0095 dev_err(&data->client->dev, "Error writing reg_conf\n");
0096 return ret;
0097 }
0098
0099 data->reg_conf = ret;
0100
0101 return 0;
0102 }
0103
0104 static void cm3323_disable(void *data)
0105 {
0106 int ret;
0107 struct iio_dev *indio_dev = data;
0108 struct cm3323_data *cm_data = iio_priv(indio_dev);
0109
0110 ret = i2c_smbus_write_word_data(cm_data->client, CM3323_CMD_CONF,
0111 CM3323_CONF_SD_BIT);
0112 if (ret < 0)
0113 dev_err(&cm_data->client->dev, "Error writing reg_conf\n");
0114 }
0115
0116 static int cm3323_set_it_bits(struct cm3323_data *data, int val, int val2)
0117 {
0118 int i, ret;
0119 u16 reg_conf;
0120
0121 for (i = 0; i < ARRAY_SIZE(cm3323_int_time); i++) {
0122 if (val == cm3323_int_time[i].val &&
0123 val2 == cm3323_int_time[i].val2) {
0124 reg_conf = data->reg_conf & ~CM3323_CONF_IT_MASK;
0125 reg_conf |= i << CM3323_CONF_IT_SHIFT;
0126
0127 ret = i2c_smbus_write_word_data(data->client,
0128 CM3323_CMD_CONF,
0129 reg_conf);
0130 if (ret < 0)
0131 return ret;
0132
0133 data->reg_conf = reg_conf;
0134
0135 return 0;
0136 }
0137 }
0138
0139 return -EINVAL;
0140 }
0141
0142 static int cm3323_get_it_bits(struct cm3323_data *data)
0143 {
0144 int bits;
0145
0146 bits = (data->reg_conf & CM3323_CONF_IT_MASK) >>
0147 CM3323_CONF_IT_SHIFT;
0148
0149 if (bits >= ARRAY_SIZE(cm3323_int_time))
0150 return -EINVAL;
0151
0152 return bits;
0153 }
0154
0155 static int cm3323_read_raw(struct iio_dev *indio_dev,
0156 struct iio_chan_spec const *chan, int *val,
0157 int *val2, long mask)
0158 {
0159 int ret;
0160 struct cm3323_data *data = iio_priv(indio_dev);
0161
0162 switch (mask) {
0163 case IIO_CHAN_INFO_RAW:
0164 mutex_lock(&data->mutex);
0165 ret = i2c_smbus_read_word_data(data->client, chan->address);
0166 if (ret < 0) {
0167 mutex_unlock(&data->mutex);
0168 return ret;
0169 }
0170 *val = ret;
0171 mutex_unlock(&data->mutex);
0172
0173 return IIO_VAL_INT;
0174 case IIO_CHAN_INFO_INT_TIME:
0175 mutex_lock(&data->mutex);
0176 ret = cm3323_get_it_bits(data);
0177 if (ret < 0) {
0178 mutex_unlock(&data->mutex);
0179 return ret;
0180 }
0181
0182 *val = cm3323_int_time[ret].val;
0183 *val2 = cm3323_int_time[ret].val2;
0184 mutex_unlock(&data->mutex);
0185
0186 return IIO_VAL_INT_PLUS_MICRO;
0187 default:
0188 return -EINVAL;
0189 }
0190 }
0191
0192 static int cm3323_write_raw(struct iio_dev *indio_dev,
0193 struct iio_chan_spec const *chan, int val,
0194 int val2, long mask)
0195 {
0196 struct cm3323_data *data = iio_priv(indio_dev);
0197 int ret;
0198
0199 switch (mask) {
0200 case IIO_CHAN_INFO_INT_TIME:
0201 mutex_lock(&data->mutex);
0202 ret = cm3323_set_it_bits(data, val, val2);
0203 mutex_unlock(&data->mutex);
0204
0205 return ret;
0206 default:
0207 return -EINVAL;
0208 }
0209 }
0210
0211 static const struct iio_info cm3323_info = {
0212 .read_raw = cm3323_read_raw,
0213 .write_raw = cm3323_write_raw,
0214 .attrs = &cm3323_attribute_group,
0215 };
0216
0217 static int cm3323_probe(struct i2c_client *client,
0218 const struct i2c_device_id *id)
0219 {
0220 struct cm3323_data *data;
0221 struct iio_dev *indio_dev;
0222 int ret;
0223
0224 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0225 if (!indio_dev)
0226 return -ENOMEM;
0227
0228 data = iio_priv(indio_dev);
0229 i2c_set_clientdata(client, indio_dev);
0230 data->client = client;
0231
0232 mutex_init(&data->mutex);
0233
0234 indio_dev->info = &cm3323_info;
0235 indio_dev->name = CM3323_DRV_NAME;
0236 indio_dev->channels = cm3323_channels;
0237 indio_dev->num_channels = ARRAY_SIZE(cm3323_channels);
0238 indio_dev->modes = INDIO_DIRECT_MODE;
0239
0240 ret = cm3323_init(indio_dev);
0241 if (ret < 0) {
0242 dev_err(&client->dev, "cm3323 chip init failed\n");
0243 return ret;
0244 }
0245
0246 ret = devm_add_action_or_reset(&client->dev, cm3323_disable, indio_dev);
0247 if (ret < 0)
0248 return ret;
0249
0250 return devm_iio_device_register(&client->dev, indio_dev);
0251 }
0252
0253 static const struct i2c_device_id cm3323_id[] = {
0254 {"cm3323", 0},
0255 {}
0256 };
0257 MODULE_DEVICE_TABLE(i2c, cm3323_id);
0258
0259 static const struct of_device_id cm3323_of_match[] = {
0260 { .compatible = "capella,cm3323", },
0261 { }
0262 };
0263 MODULE_DEVICE_TABLE(of, cm3323_of_match);
0264
0265 static struct i2c_driver cm3323_driver = {
0266 .driver = {
0267 .name = CM3323_DRV_NAME,
0268 .of_match_table = cm3323_of_match,
0269 },
0270 .probe = cm3323_probe,
0271 .id_table = cm3323_id,
0272 };
0273
0274 module_i2c_driver(cm3323_driver);
0275
0276 MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
0277 MODULE_DESCRIPTION("Capella CM3323 Color Light Sensor driver");
0278 MODULE_LICENSE("GPL v2");