This source file includes following definitions.
- vl53l0x_read_proximity
- vl53l0x_read_raw
- vl53l0x_probe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <linux/delay.h>
18 #include <linux/i2c.h>
19 #include <linux/module.h>
20
21 #include <linux/iio/iio.h>
22
23 #define VL_REG_SYSRANGE_START 0x00
24
25 #define VL_REG_SYSRANGE_MODE_MASK GENMASK(3, 0)
26 #define VL_REG_SYSRANGE_MODE_SINGLESHOT 0x00
27 #define VL_REG_SYSRANGE_MODE_START_STOP BIT(0)
28 #define VL_REG_SYSRANGE_MODE_BACKTOBACK BIT(1)
29 #define VL_REG_SYSRANGE_MODE_TIMED BIT(2)
30 #define VL_REG_SYSRANGE_MODE_HISTOGRAM BIT(3)
31
32 #define VL_REG_RESULT_INT_STATUS 0x13
33 #define VL_REG_RESULT_RANGE_STATUS 0x14
34 #define VL_REG_RESULT_RANGE_STATUS_COMPLETE BIT(0)
35
36 struct vl53l0x_data {
37 struct i2c_client *client;
38 };
39
40 static int vl53l0x_read_proximity(struct vl53l0x_data *data,
41 const struct iio_chan_spec *chan,
42 int *val)
43 {
44 struct i2c_client *client = data->client;
45 u16 tries = 20;
46 u8 buffer[12];
47 int ret;
48
49 ret = i2c_smbus_write_byte_data(client, VL_REG_SYSRANGE_START, 1);
50 if (ret < 0)
51 return ret;
52
53 do {
54 ret = i2c_smbus_read_byte_data(client,
55 VL_REG_RESULT_RANGE_STATUS);
56 if (ret < 0)
57 return ret;
58
59 if (ret & VL_REG_RESULT_RANGE_STATUS_COMPLETE)
60 break;
61
62 usleep_range(1000, 5000);
63 } while (--tries);
64 if (!tries)
65 return -ETIMEDOUT;
66
67 ret = i2c_smbus_read_i2c_block_data(client, VL_REG_RESULT_RANGE_STATUS,
68 12, buffer);
69 if (ret < 0)
70 return ret;
71 else if (ret != 12)
72 return -EREMOTEIO;
73
74
75 *val = (buffer[10] << 8) + buffer[11];
76
77 return 0;
78 }
79
80 static const struct iio_chan_spec vl53l0x_channels[] = {
81 {
82 .type = IIO_DISTANCE,
83 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
84 BIT(IIO_CHAN_INFO_SCALE),
85 },
86 };
87
88 static int vl53l0x_read_raw(struct iio_dev *indio_dev,
89 const struct iio_chan_spec *chan,
90 int *val, int *val2, long mask)
91 {
92 struct vl53l0x_data *data = iio_priv(indio_dev);
93 int ret;
94
95 if (chan->type != IIO_DISTANCE)
96 return -EINVAL;
97
98 switch (mask) {
99 case IIO_CHAN_INFO_RAW:
100 ret = vl53l0x_read_proximity(data, chan, val);
101 if (ret < 0)
102 return ret;
103
104 return IIO_VAL_INT;
105 case IIO_CHAN_INFO_SCALE:
106 *val = 0;
107 *val2 = 1000;
108
109 return IIO_VAL_INT_PLUS_MICRO;
110 default:
111 return -EINVAL;
112 }
113 }
114
115 static const struct iio_info vl53l0x_info = {
116 .read_raw = vl53l0x_read_raw,
117 };
118
119 static int vl53l0x_probe(struct i2c_client *client)
120 {
121 struct vl53l0x_data *data;
122 struct iio_dev *indio_dev;
123
124 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
125 if (!indio_dev)
126 return -ENOMEM;
127
128 data = iio_priv(indio_dev);
129 data->client = client;
130 i2c_set_clientdata(client, indio_dev);
131
132 if (!i2c_check_functionality(client->adapter,
133 I2C_FUNC_SMBUS_READ_I2C_BLOCK |
134 I2C_FUNC_SMBUS_BYTE_DATA))
135 return -EOPNOTSUPP;
136
137 indio_dev->dev.parent = &client->dev;
138 indio_dev->name = "vl53l0x";
139 indio_dev->info = &vl53l0x_info;
140 indio_dev->channels = vl53l0x_channels;
141 indio_dev->num_channels = ARRAY_SIZE(vl53l0x_channels);
142 indio_dev->modes = INDIO_DIRECT_MODE;
143
144 return devm_iio_device_register(&client->dev, indio_dev);
145 }
146
147 static const struct of_device_id st_vl53l0x_dt_match[] = {
148 { .compatible = "st,vl53l0x", },
149 { }
150 };
151 MODULE_DEVICE_TABLE(of, st_vl53l0x_dt_match);
152
153 static struct i2c_driver vl53l0x_driver = {
154 .driver = {
155 .name = "vl53l0x-i2c",
156 .of_match_table = st_vl53l0x_dt_match,
157 },
158 .probe_new = vl53l0x_probe,
159 };
160 module_i2c_driver(vl53l0x_driver);
161
162 MODULE_AUTHOR("Song Qiang <songqiang1304521@gmail.com>");
163 MODULE_DESCRIPTION("ST vl53l0x ToF ranging sensor driver");
164 MODULE_LICENSE("GPL v2");