1ac78c6aaSTomislav Denis // SPDX-License-Identifier: GPL-2.0
2ac78c6aaSTomislav Denis /*
3ac78c6aaSTomislav Denis * All Sensors DLH series low voltage digital pressure sensors
4ac78c6aaSTomislav Denis *
5ac78c6aaSTomislav Denis * Copyright (c) 2019 AVL DiTEST GmbH
6ac78c6aaSTomislav Denis * Tomislav Denis <tomislav.denis@avl.com>
7ac78c6aaSTomislav Denis *
83593cd53SAlexander A. Klimov * Datasheet: https://www.allsensors.com/cad/DS-0355_Rev_B.PDF
9ac78c6aaSTomislav Denis */
10ac78c6aaSTomislav Denis
11ac78c6aaSTomislav Denis #include <linux/module.h>
12ac78c6aaSTomislav Denis #include <linux/delay.h>
13ac78c6aaSTomislav Denis #include <linux/i2c.h>
14ac78c6aaSTomislav Denis #include <linux/iio/iio.h>
15ac78c6aaSTomislav Denis #include <linux/iio/buffer.h>
16ac78c6aaSTomislav Denis #include <linux/iio/trigger_consumer.h>
17ac78c6aaSTomislav Denis #include <linux/iio/triggered_buffer.h>
18ac78c6aaSTomislav Denis #include <asm/unaligned.h>
19ac78c6aaSTomislav Denis
20ac78c6aaSTomislav Denis /* Commands */
21ac78c6aaSTomislav Denis #define DLH_START_SINGLE 0xAA
22ac78c6aaSTomislav Denis
23ac78c6aaSTomislav Denis /* Status bits */
24ac78c6aaSTomislav Denis #define DLH_STATUS_OK 0x40
25ac78c6aaSTomislav Denis
26ac78c6aaSTomislav Denis /* DLH data format */
27ac78c6aaSTomislav Denis #define DLH_NUM_READ_BYTES 7
28ac78c6aaSTomislav Denis #define DLH_NUM_DATA_BYTES 3
29ac78c6aaSTomislav Denis #define DLH_NUM_PR_BITS 24
30ac78c6aaSTomislav Denis #define DLH_NUM_TEMP_BITS 24
31ac78c6aaSTomislav Denis
32ac78c6aaSTomislav Denis /* DLH timings */
33ac78c6aaSTomislav Denis #define DLH_SINGLE_DUT_MS 5
34ac78c6aaSTomislav Denis
35ac78c6aaSTomislav Denis enum dhl_ids {
36ac78c6aaSTomislav Denis dlhl60d,
37ac78c6aaSTomislav Denis dlhl60g,
38ac78c6aaSTomislav Denis };
39ac78c6aaSTomislav Denis
40ac78c6aaSTomislav Denis struct dlh_info {
41ac78c6aaSTomislav Denis u8 osdig; /* digital offset factor */
42ac78c6aaSTomislav Denis unsigned int fss; /* full scale span (inch H2O) */
43ac78c6aaSTomislav Denis };
44ac78c6aaSTomislav Denis
45ac78c6aaSTomislav Denis struct dlh_state {
46ac78c6aaSTomislav Denis struct i2c_client *client;
47ac78c6aaSTomislav Denis struct dlh_info info;
48ac78c6aaSTomislav Denis bool use_interrupt;
49ac78c6aaSTomislav Denis struct completion completion;
50e76330dbSJonathan Cameron u8 rx_buf[DLH_NUM_READ_BYTES];
51ac78c6aaSTomislav Denis };
52ac78c6aaSTomislav Denis
53ac78c6aaSTomislav Denis static struct dlh_info dlh_info_tbl[] = {
54ac78c6aaSTomislav Denis [dlhl60d] = {
55ac78c6aaSTomislav Denis .osdig = 2,
56ac78c6aaSTomislav Denis .fss = 120,
57ac78c6aaSTomislav Denis },
58ac78c6aaSTomislav Denis [dlhl60g] = {
59ac78c6aaSTomislav Denis .osdig = 10,
60ac78c6aaSTomislav Denis .fss = 60,
61ac78c6aaSTomislav Denis },
62ac78c6aaSTomislav Denis };
63ac78c6aaSTomislav Denis
64ac78c6aaSTomislav Denis
dlh_cmd_start_single(struct dlh_state * st)65ac78c6aaSTomislav Denis static int dlh_cmd_start_single(struct dlh_state *st)
66ac78c6aaSTomislav Denis {
67ac78c6aaSTomislav Denis int ret;
68ac78c6aaSTomislav Denis
69ac78c6aaSTomislav Denis ret = i2c_smbus_write_byte(st->client, DLH_START_SINGLE);
70ac78c6aaSTomislav Denis if (ret)
71ac78c6aaSTomislav Denis dev_err(&st->client->dev,
72ac78c6aaSTomislav Denis "%s: I2C write byte failed\n", __func__);
73ac78c6aaSTomislav Denis
74ac78c6aaSTomislav Denis return ret;
75ac78c6aaSTomislav Denis }
76ac78c6aaSTomislav Denis
dlh_cmd_read_data(struct dlh_state * st)77ac78c6aaSTomislav Denis static int dlh_cmd_read_data(struct dlh_state *st)
78ac78c6aaSTomislav Denis {
79ac78c6aaSTomislav Denis int ret;
80ac78c6aaSTomislav Denis
81ac78c6aaSTomislav Denis ret = i2c_master_recv(st->client, st->rx_buf, DLH_NUM_READ_BYTES);
82ac78c6aaSTomislav Denis if (ret < 0) {
83ac78c6aaSTomislav Denis dev_err(&st->client->dev,
84ac78c6aaSTomislav Denis "%s: I2C read block failed\n", __func__);
85ac78c6aaSTomislav Denis return ret;
86ac78c6aaSTomislav Denis }
87ac78c6aaSTomislav Denis
88ac78c6aaSTomislav Denis if (st->rx_buf[0] != DLH_STATUS_OK) {
89ac78c6aaSTomislav Denis dev_err(&st->client->dev,
90ac78c6aaSTomislav Denis "%s: invalid status 0x%02x\n", __func__, st->rx_buf[0]);
91ac78c6aaSTomislav Denis return -EBUSY;
92ac78c6aaSTomislav Denis }
93ac78c6aaSTomislav Denis
94ac78c6aaSTomislav Denis return 0;
95ac78c6aaSTomislav Denis }
96ac78c6aaSTomislav Denis
dlh_start_capture_and_read(struct dlh_state * st)97ac78c6aaSTomislav Denis static int dlh_start_capture_and_read(struct dlh_state *st)
98ac78c6aaSTomislav Denis {
99ac78c6aaSTomislav Denis int ret;
100ac78c6aaSTomislav Denis
101ac78c6aaSTomislav Denis if (st->use_interrupt)
102ac78c6aaSTomislav Denis reinit_completion(&st->completion);
103ac78c6aaSTomislav Denis
104ac78c6aaSTomislav Denis ret = dlh_cmd_start_single(st);
105ac78c6aaSTomislav Denis if (ret)
106ac78c6aaSTomislav Denis return ret;
107ac78c6aaSTomislav Denis
108ac78c6aaSTomislav Denis if (st->use_interrupt) {
109ac78c6aaSTomislav Denis ret = wait_for_completion_timeout(&st->completion,
110ac78c6aaSTomislav Denis msecs_to_jiffies(DLH_SINGLE_DUT_MS));
111ac78c6aaSTomislav Denis if (!ret) {
112ac78c6aaSTomislav Denis dev_err(&st->client->dev,
113ac78c6aaSTomislav Denis "%s: conversion timed out\n", __func__);
114ac78c6aaSTomislav Denis return -ETIMEDOUT;
115ac78c6aaSTomislav Denis }
116ac78c6aaSTomislav Denis } else {
117ac78c6aaSTomislav Denis mdelay(DLH_SINGLE_DUT_MS);
118ac78c6aaSTomislav Denis }
119ac78c6aaSTomislav Denis
120ac78c6aaSTomislav Denis return dlh_cmd_read_data(st);
121ac78c6aaSTomislav Denis }
122ac78c6aaSTomislav Denis
dlh_read_direct(struct dlh_state * st,unsigned int * pressure,unsigned int * temperature)123ac78c6aaSTomislav Denis static int dlh_read_direct(struct dlh_state *st,
124ac78c6aaSTomislav Denis unsigned int *pressure, unsigned int *temperature)
125ac78c6aaSTomislav Denis {
126ac78c6aaSTomislav Denis int ret;
127ac78c6aaSTomislav Denis
128ac78c6aaSTomislav Denis ret = dlh_start_capture_and_read(st);
129ac78c6aaSTomislav Denis if (ret)
130ac78c6aaSTomislav Denis return ret;
131ac78c6aaSTomislav Denis
132b82217e7SAndy Shevchenko *pressure = get_unaligned_be24(&st->rx_buf[1]);
133b82217e7SAndy Shevchenko *temperature = get_unaligned_be24(&st->rx_buf[4]);
134ac78c6aaSTomislav Denis
135ac78c6aaSTomislav Denis return 0;
136ac78c6aaSTomislav Denis }
137ac78c6aaSTomislav Denis
dlh_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * channel,int * value,int * value2,long mask)138ac78c6aaSTomislav Denis static int dlh_read_raw(struct iio_dev *indio_dev,
139ac78c6aaSTomislav Denis struct iio_chan_spec const *channel, int *value,
140ac78c6aaSTomislav Denis int *value2, long mask)
141ac78c6aaSTomislav Denis {
142ac78c6aaSTomislav Denis struct dlh_state *st = iio_priv(indio_dev);
143ac78c6aaSTomislav Denis unsigned int pressure, temperature;
144ac78c6aaSTomislav Denis int ret;
145ac78c6aaSTomislav Denis s64 tmp;
146ac78c6aaSTomislav Denis s32 rem;
147ac78c6aaSTomislav Denis
148ac78c6aaSTomislav Denis switch (mask) {
149ac78c6aaSTomislav Denis case IIO_CHAN_INFO_RAW:
150ac78c6aaSTomislav Denis ret = iio_device_claim_direct_mode(indio_dev);
151ac78c6aaSTomislav Denis if (ret)
152ac78c6aaSTomislav Denis return ret;
153ac78c6aaSTomislav Denis
154ac78c6aaSTomislav Denis ret = dlh_read_direct(st, &pressure, &temperature);
155ac78c6aaSTomislav Denis iio_device_release_direct_mode(indio_dev);
156ac78c6aaSTomislav Denis if (ret)
157ac78c6aaSTomislav Denis return ret;
158ac78c6aaSTomislav Denis
159ac78c6aaSTomislav Denis switch (channel->type) {
160ac78c6aaSTomislav Denis case IIO_PRESSURE:
161ac78c6aaSTomislav Denis *value = pressure;
162ac78c6aaSTomislav Denis return IIO_VAL_INT;
163ac78c6aaSTomislav Denis
164ac78c6aaSTomislav Denis case IIO_TEMP:
165ac78c6aaSTomislav Denis *value = temperature;
166ac78c6aaSTomislav Denis return IIO_VAL_INT;
167ac78c6aaSTomislav Denis
168ac78c6aaSTomislav Denis default:
169ac78c6aaSTomislav Denis return -EINVAL;
170ac78c6aaSTomislav Denis }
171ac78c6aaSTomislav Denis case IIO_CHAN_INFO_SCALE:
172ac78c6aaSTomislav Denis switch (channel->type) {
173ac78c6aaSTomislav Denis case IIO_PRESSURE:
174ac78c6aaSTomislav Denis tmp = div_s64(125LL * st->info.fss * 24909 * 100,
175ac78c6aaSTomislav Denis 1 << DLH_NUM_PR_BITS);
176ac78c6aaSTomislav Denis tmp = div_s64_rem(tmp, 1000000000LL, &rem);
177ac78c6aaSTomislav Denis *value = tmp;
178ac78c6aaSTomislav Denis *value2 = rem;
179ac78c6aaSTomislav Denis return IIO_VAL_INT_PLUS_NANO;
180ac78c6aaSTomislav Denis
181ac78c6aaSTomislav Denis case IIO_TEMP:
182ac78c6aaSTomislav Denis *value = 125 * 1000;
183ac78c6aaSTomislav Denis *value2 = DLH_NUM_TEMP_BITS;
184ac78c6aaSTomislav Denis return IIO_VAL_FRACTIONAL_LOG2;
185ac78c6aaSTomislav Denis
186ac78c6aaSTomislav Denis default:
187ac78c6aaSTomislav Denis return -EINVAL;
188ac78c6aaSTomislav Denis }
189ac78c6aaSTomislav Denis case IIO_CHAN_INFO_OFFSET:
190ac78c6aaSTomislav Denis switch (channel->type) {
191ac78c6aaSTomislav Denis case IIO_PRESSURE:
192ac78c6aaSTomislav Denis *value = -125 * st->info.fss * 24909;
193ac78c6aaSTomislav Denis *value2 = 100 * st->info.osdig * 100000;
194ac78c6aaSTomislav Denis return IIO_VAL_FRACTIONAL;
195ac78c6aaSTomislav Denis
196ac78c6aaSTomislav Denis case IIO_TEMP:
197ac78c6aaSTomislav Denis *value = -40 * 1000;
198ac78c6aaSTomislav Denis return IIO_VAL_INT;
199ac78c6aaSTomislav Denis
200ac78c6aaSTomislav Denis default:
201ac78c6aaSTomislav Denis return -EINVAL;
202ac78c6aaSTomislav Denis }
203ac78c6aaSTomislav Denis }
204ac78c6aaSTomislav Denis
205ac78c6aaSTomislav Denis return -EINVAL;
206ac78c6aaSTomislav Denis }
207ac78c6aaSTomislav Denis
208ac78c6aaSTomislav Denis static const struct iio_info dlh_info = {
209ac78c6aaSTomislav Denis .read_raw = dlh_read_raw,
210ac78c6aaSTomislav Denis };
211ac78c6aaSTomislav Denis
212ac78c6aaSTomislav Denis static const struct iio_chan_spec dlh_channels[] = {
213ac78c6aaSTomislav Denis {
214ac78c6aaSTomislav Denis .type = IIO_PRESSURE,
215ac78c6aaSTomislav Denis .indexed = 1,
216ac78c6aaSTomislav Denis .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
217ac78c6aaSTomislav Denis .info_mask_shared_by_type =
218ac78c6aaSTomislav Denis BIT(IIO_CHAN_INFO_SCALE) |
219ac78c6aaSTomislav Denis BIT(IIO_CHAN_INFO_OFFSET),
220ac78c6aaSTomislav Denis .scan_index = 0,
221ac78c6aaSTomislav Denis .scan_type = {
222ac78c6aaSTomislav Denis .sign = 'u',
223ac78c6aaSTomislav Denis .realbits = DLH_NUM_PR_BITS,
224ac78c6aaSTomislav Denis .storagebits = 32,
225ac78c6aaSTomislav Denis .shift = 8,
226ac78c6aaSTomislav Denis .endianness = IIO_BE,
227ac78c6aaSTomislav Denis },
228ac78c6aaSTomislav Denis }, {
229ac78c6aaSTomislav Denis .type = IIO_TEMP,
230ac78c6aaSTomislav Denis .indexed = 1,
231ac78c6aaSTomislav Denis .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
232ac78c6aaSTomislav Denis .info_mask_shared_by_type =
233ac78c6aaSTomislav Denis BIT(IIO_CHAN_INFO_SCALE) |
234ac78c6aaSTomislav Denis BIT(IIO_CHAN_INFO_OFFSET),
235ac78c6aaSTomislav Denis .scan_index = 1,
236ac78c6aaSTomislav Denis .scan_type = {
237ac78c6aaSTomislav Denis .sign = 'u',
238ac78c6aaSTomislav Denis .realbits = DLH_NUM_TEMP_BITS,
239ac78c6aaSTomislav Denis .storagebits = 32,
240ac78c6aaSTomislav Denis .shift = 8,
241ac78c6aaSTomislav Denis .endianness = IIO_BE,
242ac78c6aaSTomislav Denis },
243ac78c6aaSTomislav Denis }
244ac78c6aaSTomislav Denis };
245ac78c6aaSTomislav Denis
dlh_trigger_handler(int irq,void * private)246ac78c6aaSTomislav Denis static irqreturn_t dlh_trigger_handler(int irq, void *private)
247ac78c6aaSTomislav Denis {
248ac78c6aaSTomislav Denis struct iio_poll_func *pf = private;
249ac78c6aaSTomislav Denis struct iio_dev *indio_dev = pf->indio_dev;
250ac78c6aaSTomislav Denis struct dlh_state *st = iio_priv(indio_dev);
251ac78c6aaSTomislav Denis int ret;
252ac78c6aaSTomislav Denis unsigned int chn, i = 0;
253ac78c6aaSTomislav Denis __be32 tmp_buf[2];
254ac78c6aaSTomislav Denis
255ac78c6aaSTomislav Denis ret = dlh_start_capture_and_read(st);
256ac78c6aaSTomislav Denis if (ret)
257ac78c6aaSTomislav Denis goto out;
258ac78c6aaSTomislav Denis
259ac78c6aaSTomislav Denis for_each_set_bit(chn, indio_dev->active_scan_mask,
260ac78c6aaSTomislav Denis indio_dev->masklength) {
261ac78c6aaSTomislav Denis memcpy(tmp_buf + i,
262ac78c6aaSTomislav Denis &st->rx_buf[1] + chn * DLH_NUM_DATA_BYTES,
263ac78c6aaSTomislav Denis DLH_NUM_DATA_BYTES);
264ac78c6aaSTomislav Denis i++;
265ac78c6aaSTomislav Denis }
266ac78c6aaSTomislav Denis
267ac78c6aaSTomislav Denis iio_push_to_buffers(indio_dev, tmp_buf);
268ac78c6aaSTomislav Denis
269ac78c6aaSTomislav Denis out:
270ac78c6aaSTomislav Denis iio_trigger_notify_done(indio_dev->trig);
271ac78c6aaSTomislav Denis
272ac78c6aaSTomislav Denis return IRQ_HANDLED;
273ac78c6aaSTomislav Denis }
274ac78c6aaSTomislav Denis
dlh_interrupt(int irq,void * private)275ac78c6aaSTomislav Denis static irqreturn_t dlh_interrupt(int irq, void *private)
276ac78c6aaSTomislav Denis {
277ac78c6aaSTomislav Denis struct iio_dev *indio_dev = private;
278ac78c6aaSTomislav Denis struct dlh_state *st = iio_priv(indio_dev);
279ac78c6aaSTomislav Denis
280ac78c6aaSTomislav Denis complete(&st->completion);
281ac78c6aaSTomislav Denis
282ac78c6aaSTomislav Denis return IRQ_HANDLED;
283ac78c6aaSTomislav Denis };
284ac78c6aaSTomislav Denis
dlh_probe(struct i2c_client * client)285046ae105SUwe Kleine-König static int dlh_probe(struct i2c_client *client)
286ac78c6aaSTomislav Denis {
287046ae105SUwe Kleine-König const struct i2c_device_id *id = i2c_client_get_device_id(client);
288ac78c6aaSTomislav Denis struct dlh_state *st;
289ac78c6aaSTomislav Denis struct iio_dev *indio_dev;
290ac78c6aaSTomislav Denis int ret;
291ac78c6aaSTomislav Denis
292ac78c6aaSTomislav Denis if (!i2c_check_functionality(client->adapter,
293ac78c6aaSTomislav Denis I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE)) {
294ac78c6aaSTomislav Denis dev_err(&client->dev,
295ac78c6aaSTomislav Denis "adapter doesn't support required i2c functionality\n");
296ac78c6aaSTomislav Denis return -EOPNOTSUPP;
297ac78c6aaSTomislav Denis }
298ac78c6aaSTomislav Denis
299ac78c6aaSTomislav Denis indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
300ac78c6aaSTomislav Denis if (!indio_dev) {
301ac78c6aaSTomislav Denis dev_err(&client->dev, "failed to allocate iio device\n");
302ac78c6aaSTomislav Denis return -ENOMEM;
303ac78c6aaSTomislav Denis }
304ac78c6aaSTomislav Denis
305ac78c6aaSTomislav Denis i2c_set_clientdata(client, indio_dev);
306ac78c6aaSTomislav Denis
307ac78c6aaSTomislav Denis st = iio_priv(indio_dev);
308ac78c6aaSTomislav Denis st->info = dlh_info_tbl[id->driver_data];
309ac78c6aaSTomislav Denis st->client = client;
310ac78c6aaSTomislav Denis st->use_interrupt = false;
311ac78c6aaSTomislav Denis
312ac78c6aaSTomislav Denis indio_dev->name = id->name;
313ac78c6aaSTomislav Denis indio_dev->info = &dlh_info;
314ac78c6aaSTomislav Denis indio_dev->modes = INDIO_DIRECT_MODE;
315ac78c6aaSTomislav Denis indio_dev->channels = dlh_channels;
316ac78c6aaSTomislav Denis indio_dev->num_channels = ARRAY_SIZE(dlh_channels);
317ac78c6aaSTomislav Denis
318ac78c6aaSTomislav Denis if (client->irq > 0) {
319ac78c6aaSTomislav Denis ret = devm_request_threaded_irq(&client->dev, client->irq,
320ac78c6aaSTomislav Denis dlh_interrupt, NULL,
321ac78c6aaSTomislav Denis IRQF_TRIGGER_RISING | IRQF_ONESHOT,
322ac78c6aaSTomislav Denis id->name, indio_dev);
323ac78c6aaSTomislav Denis if (ret) {
324ac78c6aaSTomislav Denis dev_err(&client->dev, "failed to allocate threaded irq");
325ac78c6aaSTomislav Denis return ret;
326ac78c6aaSTomislav Denis }
327ac78c6aaSTomislav Denis
328ac78c6aaSTomislav Denis st->use_interrupt = true;
329ac78c6aaSTomislav Denis init_completion(&st->completion);
330ac78c6aaSTomislav Denis }
331ac78c6aaSTomislav Denis
332ac78c6aaSTomislav Denis ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
333ac78c6aaSTomislav Denis NULL, &dlh_trigger_handler, NULL);
334ac78c6aaSTomislav Denis if (ret) {
335ac78c6aaSTomislav Denis dev_err(&client->dev, "failed to setup iio buffer\n");
336ac78c6aaSTomislav Denis return ret;
337ac78c6aaSTomislav Denis }
338ac78c6aaSTomislav Denis
339ac78c6aaSTomislav Denis ret = devm_iio_device_register(&client->dev, indio_dev);
340ac78c6aaSTomislav Denis if (ret)
341ac78c6aaSTomislav Denis dev_err(&client->dev, "failed to register iio device\n");
342ac78c6aaSTomislav Denis
343ac78c6aaSTomislav Denis return ret;
344ac78c6aaSTomislav Denis }
345ac78c6aaSTomislav Denis
346ac78c6aaSTomislav Denis static const struct of_device_id dlh_of_match[] = {
347ac78c6aaSTomislav Denis { .compatible = "asc,dlhl60d" },
348ac78c6aaSTomislav Denis { .compatible = "asc,dlhl60g" },
349ac78c6aaSTomislav Denis {}
350ac78c6aaSTomislav Denis };
351ac78c6aaSTomislav Denis MODULE_DEVICE_TABLE(of, dlh_of_match);
352ac78c6aaSTomislav Denis
353ac78c6aaSTomislav Denis static const struct i2c_device_id dlh_id[] = {
354ac78c6aaSTomislav Denis { "dlhl60d", dlhl60d },
355ac78c6aaSTomislav Denis { "dlhl60g", dlhl60g },
356ac78c6aaSTomislav Denis {}
357ac78c6aaSTomislav Denis };
358ac78c6aaSTomislav Denis MODULE_DEVICE_TABLE(i2c, dlh_id);
359ac78c6aaSTomislav Denis
360ac78c6aaSTomislav Denis static struct i2c_driver dlh_driver = {
361ac78c6aaSTomislav Denis .driver = {
362ac78c6aaSTomislav Denis .name = "dlhl60d",
363ac78c6aaSTomislav Denis .of_match_table = dlh_of_match,
364ac78c6aaSTomislav Denis },
365*7cf15f42SUwe Kleine-König .probe = dlh_probe,
366ac78c6aaSTomislav Denis .id_table = dlh_id,
367ac78c6aaSTomislav Denis };
368ac78c6aaSTomislav Denis module_i2c_driver(dlh_driver);
369ac78c6aaSTomislav Denis
370ac78c6aaSTomislav Denis MODULE_AUTHOR("Tomislav Denis <tomislav.denis@avl.com>");
371ac78c6aaSTomislav Denis MODULE_DESCRIPTION("Driver for All Sensors DLH series pressure sensors");
372ac78c6aaSTomislav Denis MODULE_LICENSE("GPL v2");
373