0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/module.h>
0013 #include <linux/i2c.h>
0014 #include <linux/mutex.h>
0015 #include <linux/err.h>
0016 #include <linux/delay.h>
0017
0018 #include <linux/iio/iio.h>
0019 #include <linux/iio/sysfs.h>
0020
0021 #define VEML6070_DRV_NAME "veml6070"
0022
0023 #define VEML6070_ADDR_CONFIG_DATA_MSB 0x38
0024 #define VEML6070_ADDR_DATA_LSB 0x39
0025
0026 #define VEML6070_COMMAND_ACK BIT(5)
0027 #define VEML6070_COMMAND_IT GENMASK(3, 2)
0028 #define VEML6070_COMMAND_RSRVD BIT(1)
0029 #define VEML6070_COMMAND_SD BIT(0)
0030
0031 #define VEML6070_IT_10 0x04
0032
0033 struct veml6070_data {
0034 struct i2c_client *client1;
0035 struct i2c_client *client2;
0036 u8 config;
0037 struct mutex lock;
0038 };
0039
0040 static int veml6070_read(struct veml6070_data *data)
0041 {
0042 int ret;
0043 u8 msb, lsb;
0044
0045 mutex_lock(&data->lock);
0046
0047
0048 ret = i2c_smbus_write_byte(data->client1,
0049 data->config & ~VEML6070_COMMAND_SD);
0050 if (ret < 0)
0051 goto out;
0052
0053 msleep(125 + 10);
0054
0055 ret = i2c_smbus_read_byte(data->client2);
0056 if (ret < 0)
0057 goto out;
0058 msb = ret;
0059
0060 ret = i2c_smbus_read_byte(data->client1);
0061 if (ret < 0)
0062 goto out;
0063 lsb = ret;
0064
0065
0066 ret = i2c_smbus_write_byte(data->client1, data->config);
0067 if (ret < 0)
0068 goto out;
0069
0070 ret = (msb << 8) | lsb;
0071
0072 out:
0073 mutex_unlock(&data->lock);
0074 return ret;
0075 }
0076
0077 static const struct iio_chan_spec veml6070_channels[] = {
0078 {
0079 .type = IIO_INTENSITY,
0080 .modified = 1,
0081 .channel2 = IIO_MOD_LIGHT_UV,
0082 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0083 },
0084 {
0085 .type = IIO_UVINDEX,
0086 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0087 }
0088 };
0089
0090 static int veml6070_to_uv_index(unsigned val)
0091 {
0092
0093
0094
0095
0096
0097 unsigned uvi[11] = {
0098 187, 373, 560,
0099 746, 933, 1120,
0100 1308, 1494,
0101 1681, 1868, 2054};
0102 int i;
0103
0104 for (i = 0; i < ARRAY_SIZE(uvi); i++)
0105 if (val <= uvi[i])
0106 return i;
0107
0108 return 11;
0109 }
0110
0111 static int veml6070_read_raw(struct iio_dev *indio_dev,
0112 struct iio_chan_spec const *chan,
0113 int *val, int *val2, long mask)
0114 {
0115 struct veml6070_data *data = iio_priv(indio_dev);
0116 int ret;
0117
0118 switch (mask) {
0119 case IIO_CHAN_INFO_RAW:
0120 case IIO_CHAN_INFO_PROCESSED:
0121 ret = veml6070_read(data);
0122 if (ret < 0)
0123 return ret;
0124 if (mask == IIO_CHAN_INFO_PROCESSED)
0125 *val = veml6070_to_uv_index(ret);
0126 else
0127 *val = ret;
0128 return IIO_VAL_INT;
0129 default:
0130 return -EINVAL;
0131 }
0132 }
0133
0134 static const struct iio_info veml6070_info = {
0135 .read_raw = veml6070_read_raw,
0136 };
0137
0138 static int veml6070_probe(struct i2c_client *client,
0139 const struct i2c_device_id *id)
0140 {
0141 struct veml6070_data *data;
0142 struct iio_dev *indio_dev;
0143 int ret;
0144
0145 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0146 if (!indio_dev)
0147 return -ENOMEM;
0148
0149 data = iio_priv(indio_dev);
0150 i2c_set_clientdata(client, indio_dev);
0151 data->client1 = client;
0152 mutex_init(&data->lock);
0153
0154 indio_dev->info = &veml6070_info;
0155 indio_dev->channels = veml6070_channels;
0156 indio_dev->num_channels = ARRAY_SIZE(veml6070_channels);
0157 indio_dev->name = VEML6070_DRV_NAME;
0158 indio_dev->modes = INDIO_DIRECT_MODE;
0159
0160 data->client2 = i2c_new_dummy_device(client->adapter, VEML6070_ADDR_DATA_LSB);
0161 if (IS_ERR(data->client2)) {
0162 dev_err(&client->dev, "i2c device for second chip address failed\n");
0163 return PTR_ERR(data->client2);
0164 }
0165
0166 data->config = VEML6070_IT_10 | VEML6070_COMMAND_RSRVD |
0167 VEML6070_COMMAND_SD;
0168 ret = i2c_smbus_write_byte(data->client1, data->config);
0169 if (ret < 0)
0170 goto fail;
0171
0172 ret = iio_device_register(indio_dev);
0173 if (ret < 0)
0174 goto fail;
0175
0176 return ret;
0177
0178 fail:
0179 i2c_unregister_device(data->client2);
0180 return ret;
0181 }
0182
0183 static int veml6070_remove(struct i2c_client *client)
0184 {
0185 struct iio_dev *indio_dev = i2c_get_clientdata(client);
0186 struct veml6070_data *data = iio_priv(indio_dev);
0187
0188 iio_device_unregister(indio_dev);
0189 i2c_unregister_device(data->client2);
0190
0191 return 0;
0192 }
0193
0194 static const struct i2c_device_id veml6070_id[] = {
0195 { "veml6070", 0 },
0196 { }
0197 };
0198 MODULE_DEVICE_TABLE(i2c, veml6070_id);
0199
0200 static struct i2c_driver veml6070_driver = {
0201 .driver = {
0202 .name = VEML6070_DRV_NAME,
0203 },
0204 .probe = veml6070_probe,
0205 .remove = veml6070_remove,
0206 .id_table = veml6070_id,
0207 };
0208
0209 module_i2c_driver(veml6070_driver);
0210
0211 MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
0212 MODULE_DESCRIPTION("Vishay VEML6070 UV A light sensor driver");
0213 MODULE_LICENSE("GPL");