xref: /openbmc/linux/drivers/iio/pressure/dlhl60d.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
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