xref: /linux/drivers/iio/accel/stk8ba50.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
136edc939SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b9d453a5SGwendal Grignou /*
3884ca456STiberiu Breana  * Sensortek STK8BA50 3-Axis Accelerometer
4884ca456STiberiu Breana  *
5884ca456STiberiu Breana  * Copyright (c) 2015, Intel Corporation.
6884ca456STiberiu Breana  *
7884ca456STiberiu Breana  * STK8BA50 7-bit I2C address: 0x18.
8884ca456STiberiu Breana  */
9884ca456STiberiu Breana 
10884ca456STiberiu Breana #include <linux/i2c.h>
11db6a19b8STiberiu Breana #include <linux/interrupt.h>
12884ca456STiberiu Breana #include <linux/kernel.h>
13884ca456STiberiu Breana #include <linux/module.h>
14095f3ed5SJonathan Cameron #include <linux/mod_devicetable.h>
15db6a19b8STiberiu Breana #include <linux/iio/buffer.h>
16884ca456STiberiu Breana #include <linux/iio/iio.h>
17884ca456STiberiu Breana #include <linux/iio/sysfs.h>
18db6a19b8STiberiu Breana #include <linux/iio/trigger.h>
19db6a19b8STiberiu Breana #include <linux/iio/triggered_buffer.h>
20db6a19b8STiberiu Breana #include <linux/iio/trigger_consumer.h>
21884ca456STiberiu Breana 
22884ca456STiberiu Breana #define STK8BA50_REG_XOUT			0x02
23884ca456STiberiu Breana #define STK8BA50_REG_YOUT			0x04
24884ca456STiberiu Breana #define STK8BA50_REG_ZOUT			0x06
25884ca456STiberiu Breana #define STK8BA50_REG_RANGE			0x0F
26eb2c9ce2STiberiu Breana #define STK8BA50_REG_BWSEL			0x10
27884ca456STiberiu Breana #define STK8BA50_REG_POWMODE			0x11
28884ca456STiberiu Breana #define STK8BA50_REG_SWRST			0x14
29db6a19b8STiberiu Breana #define STK8BA50_REG_INTEN2			0x17
30db6a19b8STiberiu Breana #define STK8BA50_REG_INTMAP2			0x1A
31884ca456STiberiu Breana 
32884ca456STiberiu Breana #define STK8BA50_MODE_NORMAL			0
33884ca456STiberiu Breana #define STK8BA50_MODE_SUSPEND			1
34884ca456STiberiu Breana #define STK8BA50_MODE_POWERBIT			BIT(7)
35884ca456STiberiu Breana #define STK8BA50_DATA_SHIFT			6
36884ca456STiberiu Breana #define STK8BA50_RESET_CMD			0xB6
37eb2c9ce2STiberiu Breana #define STK8BA50_SR_1792HZ_IDX			7
38db6a19b8STiberiu Breana #define STK8BA50_DREADY_INT_MASK		0x10
39db6a19b8STiberiu Breana #define STK8BA50_DREADY_INT_MAP			0x81
40db6a19b8STiberiu Breana #define STK8BA50_ALL_CHANNEL_MASK		7
41db6a19b8STiberiu Breana #define STK8BA50_ALL_CHANNEL_SIZE		6
42884ca456STiberiu Breana 
43884ca456STiberiu Breana #define STK8BA50_DRIVER_NAME			"stk8ba50"
44db6a19b8STiberiu Breana #define STK8BA50_IRQ_NAME			"stk8ba50_event"
45884ca456STiberiu Breana 
46884ca456STiberiu Breana #define STK8BA50_SCALE_AVAIL			"0.0384 0.0767 0.1534 0.3069"
47884ca456STiberiu Breana 
48884ca456STiberiu Breana /*
49884ca456STiberiu Breana  * The accelerometer has four measurement ranges:
50884ca456STiberiu Breana  * +/-2g; +/-4g; +/-8g; +/-16g
51884ca456STiberiu Breana  *
52884ca456STiberiu Breana  * Acceleration values are 10-bit, 2's complement.
53884ca456STiberiu Breana  * Scales are calculated as following:
54884ca456STiberiu Breana  *
55884ca456STiberiu Breana  * scale1 = (2 + 2) * 9.81 / (2^10 - 1)   = 0.0384
56884ca456STiberiu Breana  * scale2 = (4 + 4) * 9.81 / (2^10 - 1)   = 0.0767
57884ca456STiberiu Breana  * etc.
58884ca456STiberiu Breana  *
59884ca456STiberiu Breana  * Scales are stored in this format:
60884ca456STiberiu Breana  * { <register value>, <scale value> }
61884ca456STiberiu Breana  *
62884ca456STiberiu Breana  * Locally, the range is stored as a table index.
63884ca456STiberiu Breana  */
64003f4880STiberiu Breana static const struct {
65003f4880STiberiu Breana 	u8 reg_val;
66003f4880STiberiu Breana 	u32 scale_val;
67003f4880STiberiu Breana } stk8ba50_scale_table[] = {
68884ca456STiberiu Breana 	{3, 38400}, {5, 76700}, {8, 153400}, {12, 306900}
69884ca456STiberiu Breana };
70884ca456STiberiu Breana 
71eb2c9ce2STiberiu Breana /* Sample rates are stored as { <register value>, <Hz value> } */
72eb2c9ce2STiberiu Breana static const struct {
73eb2c9ce2STiberiu Breana 	u8 reg_val;
74eb2c9ce2STiberiu Breana 	u16 samp_freq;
75eb2c9ce2STiberiu Breana } stk8ba50_samp_freq_table[] = {
76eb2c9ce2STiberiu Breana 	{0x08, 14},  {0x09, 25},  {0x0A, 56},  {0x0B, 112},
77eb2c9ce2STiberiu Breana 	{0x0C, 224}, {0x0D, 448}, {0x0E, 896}, {0x0F, 1792}
78eb2c9ce2STiberiu Breana };
79eb2c9ce2STiberiu Breana 
80db6a19b8STiberiu Breana /* Used to map scan mask bits to their corresponding channel register. */
81db6a19b8STiberiu Breana static const int stk8ba50_channel_table[] = {
82db6a19b8STiberiu Breana 	STK8BA50_REG_XOUT,
83db6a19b8STiberiu Breana 	STK8BA50_REG_YOUT,
84db6a19b8STiberiu Breana 	STK8BA50_REG_ZOUT
85db6a19b8STiberiu Breana };
86db6a19b8STiberiu Breana 
87884ca456STiberiu Breana struct stk8ba50_data {
88884ca456STiberiu Breana 	struct i2c_client *client;
89884ca456STiberiu Breana 	struct mutex lock;
90884ca456STiberiu Breana 	int range;
91eb2c9ce2STiberiu Breana 	u8 sample_rate_idx;
92db6a19b8STiberiu Breana 	struct iio_trigger *dready_trig;
93db6a19b8STiberiu Breana 	bool dready_trigger_on;
9433488389SJonathan Cameron 	/* Ensure timestamp is naturally aligned */
9533488389SJonathan Cameron 	struct {
9633488389SJonathan Cameron 		s16 chans[3];
9733488389SJonathan Cameron 		s64 timetamp __aligned(8);
9833488389SJonathan Cameron 	} scan;
99884ca456STiberiu Breana };
100884ca456STiberiu Breana 
101db6a19b8STiberiu Breana #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) {			\
102884ca456STiberiu Breana 	.type = IIO_ACCEL,						\
103884ca456STiberiu Breana 	.address = reg,							\
104884ca456STiberiu Breana 	.modified = 1,							\
105884ca456STiberiu Breana 	.channel2 = IIO_MOD_##axis,					\
106884ca456STiberiu Breana 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),			\
107884ca456STiberiu Breana 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),		\
108eb2c9ce2STiberiu Breana 				    BIT(IIO_CHAN_INFO_SAMP_FREQ),	\
109db6a19b8STiberiu Breana 	.scan_index = index,						\
110db6a19b8STiberiu Breana 	.scan_type = {							\
111db6a19b8STiberiu Breana 		.sign = 's',						\
112db6a19b8STiberiu Breana 		.realbits = 10,						\
113db6a19b8STiberiu Breana 		.storagebits = 16,					\
114db6a19b8STiberiu Breana 		.shift = STK8BA50_DATA_SHIFT,				\
115db6a19b8STiberiu Breana 		.endianness = IIO_CPU,					\
116db6a19b8STiberiu Breana 	},								\
117884ca456STiberiu Breana }
118884ca456STiberiu Breana 
119884ca456STiberiu Breana static const struct iio_chan_spec stk8ba50_channels[] = {
120db6a19b8STiberiu Breana 	STK8BA50_ACCEL_CHANNEL(0, STK8BA50_REG_XOUT, X),
121db6a19b8STiberiu Breana 	STK8BA50_ACCEL_CHANNEL(1, STK8BA50_REG_YOUT, Y),
122db6a19b8STiberiu Breana 	STK8BA50_ACCEL_CHANNEL(2, STK8BA50_REG_ZOUT, Z),
123db6a19b8STiberiu Breana 	IIO_CHAN_SOFT_TIMESTAMP(3),
124884ca456STiberiu Breana };
125884ca456STiberiu Breana 
126884ca456STiberiu Breana static IIO_CONST_ATTR(in_accel_scale_available, STK8BA50_SCALE_AVAIL);
127884ca456STiberiu Breana 
128eb2c9ce2STiberiu Breana static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("14 25 56 112 224 448 896 1792");
129eb2c9ce2STiberiu Breana 
130884ca456STiberiu Breana static struct attribute *stk8ba50_attributes[] = {
131884ca456STiberiu Breana 	&iio_const_attr_in_accel_scale_available.dev_attr.attr,
132eb2c9ce2STiberiu Breana 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
133884ca456STiberiu Breana 	NULL,
134884ca456STiberiu Breana };
135884ca456STiberiu Breana 
136884ca456STiberiu Breana static const struct attribute_group stk8ba50_attribute_group = {
137884ca456STiberiu Breana 	.attrs = stk8ba50_attributes
138884ca456STiberiu Breana };
139884ca456STiberiu Breana 
stk8ba50_read_accel(struct stk8ba50_data * data,u8 reg)140884ca456STiberiu Breana static int stk8ba50_read_accel(struct stk8ba50_data *data, u8 reg)
141884ca456STiberiu Breana {
142884ca456STiberiu Breana 	int ret;
143884ca456STiberiu Breana 	struct i2c_client *client = data->client;
144884ca456STiberiu Breana 
145884ca456STiberiu Breana 	ret = i2c_smbus_read_word_data(client, reg);
146884ca456STiberiu Breana 	if (ret < 0) {
147884ca456STiberiu Breana 		dev_err(&client->dev, "register read failed\n");
148884ca456STiberiu Breana 		return ret;
149884ca456STiberiu Breana 	}
150884ca456STiberiu Breana 
151db6a19b8STiberiu Breana 	return ret;
152db6a19b8STiberiu Breana }
153db6a19b8STiberiu Breana 
stk8ba50_data_rdy_trigger_set_state(struct iio_trigger * trig,bool state)154db6a19b8STiberiu Breana static int stk8ba50_data_rdy_trigger_set_state(struct iio_trigger *trig,
155db6a19b8STiberiu Breana 					       bool state)
156db6a19b8STiberiu Breana {
157db6a19b8STiberiu Breana 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
158db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
159db6a19b8STiberiu Breana 	int ret;
160db6a19b8STiberiu Breana 
161db6a19b8STiberiu Breana 	if (state)
162db6a19b8STiberiu Breana 		ret = i2c_smbus_write_byte_data(data->client,
163db6a19b8STiberiu Breana 			STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
164db6a19b8STiberiu Breana 	else
165db6a19b8STiberiu Breana 		ret = i2c_smbus_write_byte_data(data->client,
166db6a19b8STiberiu Breana 			STK8BA50_REG_INTEN2, 0x00);
167db6a19b8STiberiu Breana 
168db6a19b8STiberiu Breana 	if (ret < 0)
169db6a19b8STiberiu Breana 		dev_err(&data->client->dev, "failed to set trigger state\n");
170db6a19b8STiberiu Breana 	else
171db6a19b8STiberiu Breana 		data->dready_trigger_on = state;
172db6a19b8STiberiu Breana 
173db6a19b8STiberiu Breana 	return ret;
174db6a19b8STiberiu Breana }
175db6a19b8STiberiu Breana 
176db6a19b8STiberiu Breana static const struct iio_trigger_ops stk8ba50_trigger_ops = {
177db6a19b8STiberiu Breana 	.set_trigger_state = stk8ba50_data_rdy_trigger_set_state,
178db6a19b8STiberiu Breana };
179db6a19b8STiberiu Breana 
stk8ba50_set_power(struct stk8ba50_data * data,bool mode)180db6a19b8STiberiu Breana static int stk8ba50_set_power(struct stk8ba50_data *data, bool mode)
181db6a19b8STiberiu Breana {
182db6a19b8STiberiu Breana 	int ret;
183db6a19b8STiberiu Breana 	u8 masked_reg;
184db6a19b8STiberiu Breana 	struct i2c_client *client = data->client;
185db6a19b8STiberiu Breana 
186db6a19b8STiberiu Breana 	ret = i2c_smbus_read_byte_data(client, STK8BA50_REG_POWMODE);
187db6a19b8STiberiu Breana 	if (ret < 0)
188db6a19b8STiberiu Breana 		goto exit_err;
189db6a19b8STiberiu Breana 
190db6a19b8STiberiu Breana 	if (mode)
191db6a19b8STiberiu Breana 		masked_reg = ret | STK8BA50_MODE_POWERBIT;
192db6a19b8STiberiu Breana 	else
193db6a19b8STiberiu Breana 		masked_reg = ret & (~STK8BA50_MODE_POWERBIT);
194db6a19b8STiberiu Breana 
195db6a19b8STiberiu Breana 	ret = i2c_smbus_write_byte_data(client, STK8BA50_REG_POWMODE,
196db6a19b8STiberiu Breana 					masked_reg);
197db6a19b8STiberiu Breana 	if (ret < 0)
198db6a19b8STiberiu Breana 		goto exit_err;
199db6a19b8STiberiu Breana 
200db6a19b8STiberiu Breana 	return ret;
201db6a19b8STiberiu Breana 
202db6a19b8STiberiu Breana exit_err:
203db6a19b8STiberiu Breana 	dev_err(&client->dev, "failed to change sensor mode\n");
204db6a19b8STiberiu Breana 	return ret;
205884ca456STiberiu Breana }
206884ca456STiberiu Breana 
stk8ba50_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)207884ca456STiberiu Breana static int stk8ba50_read_raw(struct iio_dev *indio_dev,
208884ca456STiberiu Breana 			     struct iio_chan_spec const *chan,
209884ca456STiberiu Breana 			     int *val, int *val2, long mask)
210884ca456STiberiu Breana {
211884ca456STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
212db6a19b8STiberiu Breana 	int ret;
213884ca456STiberiu Breana 
214884ca456STiberiu Breana 	switch (mask) {
215884ca456STiberiu Breana 	case IIO_CHAN_INFO_RAW:
216db6a19b8STiberiu Breana 		if (iio_buffer_enabled(indio_dev))
217db6a19b8STiberiu Breana 			return -EBUSY;
218884ca456STiberiu Breana 		mutex_lock(&data->lock);
219db6a19b8STiberiu Breana 		ret = stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
220db6a19b8STiberiu Breana 		if (ret < 0) {
221db6a19b8STiberiu Breana 			mutex_unlock(&data->lock);
222db6a19b8STiberiu Breana 			return -EINVAL;
223db6a19b8STiberiu Breana 		}
224db6a19b8STiberiu Breana 		ret = stk8ba50_read_accel(data, chan->address);
225db6a19b8STiberiu Breana 		if (ret < 0) {
226db6a19b8STiberiu Breana 			stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
227db6a19b8STiberiu Breana 			mutex_unlock(&data->lock);
228db6a19b8STiberiu Breana 			return -EINVAL;
229db6a19b8STiberiu Breana 		}
230ded408b1SGwendal Grignou 		*val = sign_extend32(ret >> chan->scan_type.shift,
231ded408b1SGwendal Grignou 				     chan->scan_type.realbits - 1);
232db6a19b8STiberiu Breana 		stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
233884ca456STiberiu Breana 		mutex_unlock(&data->lock);
234884ca456STiberiu Breana 		return IIO_VAL_INT;
235884ca456STiberiu Breana 	case IIO_CHAN_INFO_SCALE:
236884ca456STiberiu Breana 		*val = 0;
237003f4880STiberiu Breana 		*val2 = stk8ba50_scale_table[data->range].scale_val;
238884ca456STiberiu Breana 		return IIO_VAL_INT_PLUS_MICRO;
239eb2c9ce2STiberiu Breana 	case IIO_CHAN_INFO_SAMP_FREQ:
240eb2c9ce2STiberiu Breana 		*val = stk8ba50_samp_freq_table
241eb2c9ce2STiberiu Breana 				[data->sample_rate_idx].samp_freq;
242eb2c9ce2STiberiu Breana 		*val2 = 0;
243eb2c9ce2STiberiu Breana 		return IIO_VAL_INT;
244884ca456STiberiu Breana 	}
245884ca456STiberiu Breana 
246884ca456STiberiu Breana 	return -EINVAL;
247884ca456STiberiu Breana }
248884ca456STiberiu Breana 
stk8ba50_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)249884ca456STiberiu Breana static int stk8ba50_write_raw(struct iio_dev *indio_dev,
250884ca456STiberiu Breana 			      struct iio_chan_spec const *chan,
251884ca456STiberiu Breana 			      int val, int val2, long mask)
252884ca456STiberiu Breana {
253884ca456STiberiu Breana 	int ret;
254884ca456STiberiu Breana 	int i;
255884ca456STiberiu Breana 	int index = -1;
256884ca456STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
257884ca456STiberiu Breana 
258884ca456STiberiu Breana 	switch (mask) {
259884ca456STiberiu Breana 	case IIO_CHAN_INFO_SCALE:
260884ca456STiberiu Breana 		if (val != 0)
261884ca456STiberiu Breana 			return -EINVAL;
262884ca456STiberiu Breana 
263884ca456STiberiu Breana 		for (i = 0; i < ARRAY_SIZE(stk8ba50_scale_table); i++)
264003f4880STiberiu Breana 			if (val2 == stk8ba50_scale_table[i].scale_val) {
265884ca456STiberiu Breana 				index = i;
266884ca456STiberiu Breana 				break;
267884ca456STiberiu Breana 			}
268884ca456STiberiu Breana 		if (index < 0)
269884ca456STiberiu Breana 			return -EINVAL;
270884ca456STiberiu Breana 
271884ca456STiberiu Breana 		ret = i2c_smbus_write_byte_data(data->client,
272884ca456STiberiu Breana 				STK8BA50_REG_RANGE,
273003f4880STiberiu Breana 				stk8ba50_scale_table[index].reg_val);
274884ca456STiberiu Breana 		if (ret < 0)
275884ca456STiberiu Breana 			dev_err(&data->client->dev,
276884ca456STiberiu Breana 					"failed to set measurement range\n");
277884ca456STiberiu Breana 		else
278884ca456STiberiu Breana 			data->range = index;
279884ca456STiberiu Breana 
280884ca456STiberiu Breana 		return ret;
281eb2c9ce2STiberiu Breana 	case IIO_CHAN_INFO_SAMP_FREQ:
282eb2c9ce2STiberiu Breana 		for (i = 0; i < ARRAY_SIZE(stk8ba50_samp_freq_table); i++)
283eb2c9ce2STiberiu Breana 			if (val == stk8ba50_samp_freq_table[i].samp_freq) {
284eb2c9ce2STiberiu Breana 				index = i;
285eb2c9ce2STiberiu Breana 				break;
286eb2c9ce2STiberiu Breana 			}
287eb2c9ce2STiberiu Breana 		if (index < 0)
288eb2c9ce2STiberiu Breana 			return -EINVAL;
289eb2c9ce2STiberiu Breana 
290eb2c9ce2STiberiu Breana 		ret = i2c_smbus_write_byte_data(data->client,
291eb2c9ce2STiberiu Breana 				STK8BA50_REG_BWSEL,
292eb2c9ce2STiberiu Breana 				stk8ba50_samp_freq_table[index].reg_val);
293eb2c9ce2STiberiu Breana 		if (ret < 0)
294eb2c9ce2STiberiu Breana 			dev_err(&data->client->dev,
295eb2c9ce2STiberiu Breana 					"failed to set sampling rate\n");
296eb2c9ce2STiberiu Breana 		else
297eb2c9ce2STiberiu Breana 			data->sample_rate_idx = index;
298eb2c9ce2STiberiu Breana 
299eb2c9ce2STiberiu Breana 		return ret;
300884ca456STiberiu Breana 	}
301884ca456STiberiu Breana 
302884ca456STiberiu Breana 	return -EINVAL;
303884ca456STiberiu Breana }
304884ca456STiberiu Breana 
305884ca456STiberiu Breana static const struct iio_info stk8ba50_info = {
306884ca456STiberiu Breana 	.read_raw		= stk8ba50_read_raw,
307884ca456STiberiu Breana 	.write_raw		= stk8ba50_write_raw,
308884ca456STiberiu Breana 	.attrs			= &stk8ba50_attribute_group,
309884ca456STiberiu Breana };
310884ca456STiberiu Breana 
stk8ba50_trigger_handler(int irq,void * p)311db6a19b8STiberiu Breana static irqreturn_t stk8ba50_trigger_handler(int irq, void *p)
312884ca456STiberiu Breana {
313db6a19b8STiberiu Breana 	struct iio_poll_func *pf = p;
314db6a19b8STiberiu Breana 	struct iio_dev *indio_dev = pf->indio_dev;
315db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
316db6a19b8STiberiu Breana 	int bit, ret, i = 0;
317db6a19b8STiberiu Breana 
318db6a19b8STiberiu Breana 	mutex_lock(&data->lock);
319db6a19b8STiberiu Breana 	/*
320db6a19b8STiberiu Breana 	 * Do a bulk read if all channels are requested,
321db6a19b8STiberiu Breana 	 * from 0x02 (XOUT1) to 0x07 (ZOUT2)
322db6a19b8STiberiu Breana 	 */
323db6a19b8STiberiu Breana 	if (*(indio_dev->active_scan_mask) == STK8BA50_ALL_CHANNEL_MASK) {
324db6a19b8STiberiu Breana 		ret = i2c_smbus_read_i2c_block_data(data->client,
325db6a19b8STiberiu Breana 						    STK8BA50_REG_XOUT,
326db6a19b8STiberiu Breana 						    STK8BA50_ALL_CHANNEL_SIZE,
32733488389SJonathan Cameron 						    (u8 *)data->scan.chans);
328db6a19b8STiberiu Breana 		if (ret < STK8BA50_ALL_CHANNEL_SIZE) {
329db6a19b8STiberiu Breana 			dev_err(&data->client->dev, "register read failed\n");
330db6a19b8STiberiu Breana 			goto err;
331db6a19b8STiberiu Breana 		}
332db6a19b8STiberiu Breana 	} else {
333*d637a64dSNuno Sa 		iio_for_each_active_channel(indio_dev, bit) {
334db6a19b8STiberiu Breana 			ret = stk8ba50_read_accel(data,
335db6a19b8STiberiu Breana 						  stk8ba50_channel_table[bit]);
336db6a19b8STiberiu Breana 			if (ret < 0)
337db6a19b8STiberiu Breana 				goto err;
338db6a19b8STiberiu Breana 
33933488389SJonathan Cameron 			data->scan.chans[i++] = ret;
340db6a19b8STiberiu Breana 		}
341db6a19b8STiberiu Breana 	}
34233488389SJonathan Cameron 	iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
343db6a19b8STiberiu Breana 					   pf->timestamp);
344db6a19b8STiberiu Breana err:
345db6a19b8STiberiu Breana 	mutex_unlock(&data->lock);
346db6a19b8STiberiu Breana 	iio_trigger_notify_done(indio_dev->trig);
347db6a19b8STiberiu Breana 
348db6a19b8STiberiu Breana 	return IRQ_HANDLED;
349db6a19b8STiberiu Breana }
350db6a19b8STiberiu Breana 
stk8ba50_data_rdy_trig_poll(int irq,void * private)351db6a19b8STiberiu Breana static irqreturn_t stk8ba50_data_rdy_trig_poll(int irq, void *private)
352db6a19b8STiberiu Breana {
353db6a19b8STiberiu Breana 	struct iio_dev *indio_dev = private;
354db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
355db6a19b8STiberiu Breana 
356db6a19b8STiberiu Breana 	if (data->dready_trigger_on)
357db6a19b8STiberiu Breana 		iio_trigger_poll(data->dready_trig);
358db6a19b8STiberiu Breana 
359db6a19b8STiberiu Breana 	return IRQ_HANDLED;
360db6a19b8STiberiu Breana }
361db6a19b8STiberiu Breana 
stk8ba50_buffer_preenable(struct iio_dev * indio_dev)362db6a19b8STiberiu Breana static int stk8ba50_buffer_preenable(struct iio_dev *indio_dev)
363db6a19b8STiberiu Breana {
364db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
365db6a19b8STiberiu Breana 
366db6a19b8STiberiu Breana 	return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
367db6a19b8STiberiu Breana }
368db6a19b8STiberiu Breana 
stk8ba50_buffer_postdisable(struct iio_dev * indio_dev)369db6a19b8STiberiu Breana static int stk8ba50_buffer_postdisable(struct iio_dev *indio_dev)
370db6a19b8STiberiu Breana {
371db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
372db6a19b8STiberiu Breana 
373db6a19b8STiberiu Breana 	return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
374db6a19b8STiberiu Breana }
375db6a19b8STiberiu Breana 
376db6a19b8STiberiu Breana static const struct iio_buffer_setup_ops stk8ba50_buffer_setup_ops = {
377db6a19b8STiberiu Breana 	.preenable   = stk8ba50_buffer_preenable,
378db6a19b8STiberiu Breana 	.postdisable = stk8ba50_buffer_postdisable,
379db6a19b8STiberiu Breana };
380db6a19b8STiberiu Breana 
stk8ba50_probe(struct i2c_client * client)381d18e7060SUwe Kleine-König static int stk8ba50_probe(struct i2c_client *client)
382884ca456STiberiu Breana {
383884ca456STiberiu Breana 	int ret;
384884ca456STiberiu Breana 	struct iio_dev *indio_dev;
385884ca456STiberiu Breana 	struct stk8ba50_data *data;
386884ca456STiberiu Breana 
387884ca456STiberiu Breana 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
388884ca456STiberiu Breana 	if (!indio_dev) {
389884ca456STiberiu Breana 		dev_err(&client->dev, "iio allocation failed!\n");
390884ca456STiberiu Breana 		return -ENOMEM;
391884ca456STiberiu Breana 	}
392884ca456STiberiu Breana 
393884ca456STiberiu Breana 	data = iio_priv(indio_dev);
394884ca456STiberiu Breana 	data->client = client;
395884ca456STiberiu Breana 	i2c_set_clientdata(client, indio_dev);
396884ca456STiberiu Breana 	mutex_init(&data->lock);
397884ca456STiberiu Breana 
398884ca456STiberiu Breana 	indio_dev->info = &stk8ba50_info;
399884ca456STiberiu Breana 	indio_dev->name = STK8BA50_DRIVER_NAME;
400884ca456STiberiu Breana 	indio_dev->modes = INDIO_DIRECT_MODE;
401884ca456STiberiu Breana 	indio_dev->channels = stk8ba50_channels;
402884ca456STiberiu Breana 	indio_dev->num_channels = ARRAY_SIZE(stk8ba50_channels);
403884ca456STiberiu Breana 
404884ca456STiberiu Breana 	/* Reset all registers on startup */
405884ca456STiberiu Breana 	ret = i2c_smbus_write_byte_data(client,
406884ca456STiberiu Breana 			STK8BA50_REG_SWRST, STK8BA50_RESET_CMD);
407884ca456STiberiu Breana 	if (ret < 0) {
408884ca456STiberiu Breana 		dev_err(&client->dev, "failed to reset sensor\n");
409db42a9beSTiberiu Breana 		goto err_power_off;
410884ca456STiberiu Breana 	}
411884ca456STiberiu Breana 
412884ca456STiberiu Breana 	/* The default range is +/-2g */
413884ca456STiberiu Breana 	data->range = 0;
414884ca456STiberiu Breana 
415eb2c9ce2STiberiu Breana 	/* The default sampling rate is 1792 Hz (maximum) */
416eb2c9ce2STiberiu Breana 	data->sample_rate_idx = STK8BA50_SR_1792HZ_IDX;
417eb2c9ce2STiberiu Breana 
418db6a19b8STiberiu Breana 	/* Set up interrupts */
419db6a19b8STiberiu Breana 	ret = i2c_smbus_write_byte_data(client,
420db6a19b8STiberiu Breana 			STK8BA50_REG_INTEN2, STK8BA50_DREADY_INT_MASK);
421db6a19b8STiberiu Breana 	if (ret < 0) {
422db6a19b8STiberiu Breana 		dev_err(&client->dev, "failed to set up interrupts\n");
423db6a19b8STiberiu Breana 		goto err_power_off;
424db6a19b8STiberiu Breana 	}
425db6a19b8STiberiu Breana 	ret = i2c_smbus_write_byte_data(client,
426db6a19b8STiberiu Breana 			STK8BA50_REG_INTMAP2, STK8BA50_DREADY_INT_MAP);
427db6a19b8STiberiu Breana 	if (ret < 0) {
428db6a19b8STiberiu Breana 		dev_err(&client->dev, "failed to set up interrupts\n");
429db6a19b8STiberiu Breana 		goto err_power_off;
430db6a19b8STiberiu Breana 	}
431db6a19b8STiberiu Breana 
4326839c1b0SOctavian Purdila 	if (client->irq > 0) {
433db6a19b8STiberiu Breana 		ret = devm_request_threaded_irq(&client->dev, client->irq,
434db6a19b8STiberiu Breana 						stk8ba50_data_rdy_trig_poll,
435db6a19b8STiberiu Breana 						NULL,
436db6a19b8STiberiu Breana 						IRQF_TRIGGER_RISING |
437db6a19b8STiberiu Breana 						IRQF_ONESHOT,
438db6a19b8STiberiu Breana 						STK8BA50_IRQ_NAME,
439db6a19b8STiberiu Breana 						indio_dev);
440db6a19b8STiberiu Breana 		if (ret < 0) {
441db6a19b8STiberiu Breana 			dev_err(&client->dev, "request irq %d failed\n",
442db6a19b8STiberiu Breana 				client->irq);
443db6a19b8STiberiu Breana 			goto err_power_off;
444db6a19b8STiberiu Breana 		}
445db6a19b8STiberiu Breana 
446db6a19b8STiberiu Breana 		data->dready_trig = devm_iio_trigger_alloc(&client->dev,
447db6a19b8STiberiu Breana 							   "%s-dev%d",
448db6a19b8STiberiu Breana 							   indio_dev->name,
44915ea2878SJonathan Cameron 							   iio_device_id(indio_dev));
450db6a19b8STiberiu Breana 		if (!data->dready_trig) {
451db6a19b8STiberiu Breana 			ret = -ENOMEM;
452db6a19b8STiberiu Breana 			goto err_power_off;
453db6a19b8STiberiu Breana 		}
454db6a19b8STiberiu Breana 
455db6a19b8STiberiu Breana 		data->dready_trig->ops = &stk8ba50_trigger_ops;
456db6a19b8STiberiu Breana 		iio_trigger_set_drvdata(data->dready_trig, indio_dev);
457db6a19b8STiberiu Breana 		ret = iio_trigger_register(data->dready_trig);
458db6a19b8STiberiu Breana 		if (ret) {
459db6a19b8STiberiu Breana 			dev_err(&client->dev, "iio trigger register failed\n");
460db6a19b8STiberiu Breana 			goto err_power_off;
461db6a19b8STiberiu Breana 		}
462db6a19b8STiberiu Breana 	}
463db6a19b8STiberiu Breana 
464db6a19b8STiberiu Breana 	ret = iio_triggered_buffer_setup(indio_dev,
465db6a19b8STiberiu Breana 					 iio_pollfunc_store_time,
466db6a19b8STiberiu Breana 					 stk8ba50_trigger_handler,
467db6a19b8STiberiu Breana 					 &stk8ba50_buffer_setup_ops);
468db6a19b8STiberiu Breana 	if (ret < 0) {
469db6a19b8STiberiu Breana 		dev_err(&client->dev, "iio triggered buffer setup failed\n");
470db6a19b8STiberiu Breana 		goto err_trigger_unregister;
471db6a19b8STiberiu Breana 	}
472db6a19b8STiberiu Breana 
473884ca456STiberiu Breana 	ret = iio_device_register(indio_dev);
474884ca456STiberiu Breana 	if (ret < 0) {
475884ca456STiberiu Breana 		dev_err(&client->dev, "device_register failed\n");
476db6a19b8STiberiu Breana 		goto err_buffer_cleanup;
477884ca456STiberiu Breana 	}
478884ca456STiberiu Breana 
479884ca456STiberiu Breana 	return ret;
480db42a9beSTiberiu Breana 
481db6a19b8STiberiu Breana err_buffer_cleanup:
482db6a19b8STiberiu Breana 	iio_triggered_buffer_cleanup(indio_dev);
483db6a19b8STiberiu Breana err_trigger_unregister:
484db6a19b8STiberiu Breana 	if (data->dready_trig)
485db6a19b8STiberiu Breana 		iio_trigger_unregister(data->dready_trig);
486db42a9beSTiberiu Breana err_power_off:
487db42a9beSTiberiu Breana 	stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
488db42a9beSTiberiu Breana 	return ret;
489884ca456STiberiu Breana }
490884ca456STiberiu Breana 
stk8ba50_remove(struct i2c_client * client)491ed5c2f5fSUwe Kleine-König static void stk8ba50_remove(struct i2c_client *client)
492884ca456STiberiu Breana {
493884ca456STiberiu Breana 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
494db6a19b8STiberiu Breana 	struct stk8ba50_data *data = iio_priv(indio_dev);
495884ca456STiberiu Breana 
496884ca456STiberiu Breana 	iio_device_unregister(indio_dev);
497db6a19b8STiberiu Breana 	iio_triggered_buffer_cleanup(indio_dev);
498884ca456STiberiu Breana 
499db6a19b8STiberiu Breana 	if (data->dready_trig)
500db6a19b8STiberiu Breana 		iio_trigger_unregister(data->dready_trig);
501db6a19b8STiberiu Breana 
5021db6926dSUwe Kleine-König 	stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
503884ca456STiberiu Breana }
504884ca456STiberiu Breana 
stk8ba50_suspend(struct device * dev)505884ca456STiberiu Breana static int stk8ba50_suspend(struct device *dev)
506884ca456STiberiu Breana {
507884ca456STiberiu Breana 	struct stk8ba50_data *data;
508884ca456STiberiu Breana 
509884ca456STiberiu Breana 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
510884ca456STiberiu Breana 
511884ca456STiberiu Breana 	return stk8ba50_set_power(data, STK8BA50_MODE_SUSPEND);
512884ca456STiberiu Breana }
513884ca456STiberiu Breana 
stk8ba50_resume(struct device * dev)514884ca456STiberiu Breana static int stk8ba50_resume(struct device *dev)
515884ca456STiberiu Breana {
516884ca456STiberiu Breana 	struct stk8ba50_data *data;
517884ca456STiberiu Breana 
518884ca456STiberiu Breana 	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
519884ca456STiberiu Breana 
520884ca456STiberiu Breana 	return stk8ba50_set_power(data, STK8BA50_MODE_NORMAL);
521884ca456STiberiu Breana }
522884ca456STiberiu Breana 
5230c74ef35SJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend,
5240c74ef35SJonathan Cameron 				stk8ba50_resume);
525884ca456STiberiu Breana 
526884ca456STiberiu Breana static const struct i2c_device_id stk8ba50_i2c_id[] = {
5274391affaSUwe Kleine-König 	{ "stk8ba50" },
528884ca456STiberiu Breana 	{}
529884ca456STiberiu Breana };
53058e446fcSJavier Martinez Canillas MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id);
531884ca456STiberiu Breana 
532884ca456STiberiu Breana static const struct acpi_device_id stk8ba50_acpi_id[] = {
533884ca456STiberiu Breana 	{"STK8BA50", 0},
534884ca456STiberiu Breana 	{}
535884ca456STiberiu Breana };
536884ca456STiberiu Breana 
537884ca456STiberiu Breana MODULE_DEVICE_TABLE(acpi, stk8ba50_acpi_id);
538884ca456STiberiu Breana 
539884ca456STiberiu Breana static struct i2c_driver stk8ba50_driver = {
540884ca456STiberiu Breana 	.driver = {
541884ca456STiberiu Breana 		.name = "stk8ba50",
5420c74ef35SJonathan Cameron 		.pm = pm_sleep_ptr(&stk8ba50_pm_ops),
543095f3ed5SJonathan Cameron 		.acpi_match_table = stk8ba50_acpi_id,
544884ca456STiberiu Breana 	},
5457cf15f42SUwe Kleine-König 	.probe =        stk8ba50_probe,
546884ca456STiberiu Breana 	.remove =           stk8ba50_remove,
547884ca456STiberiu Breana 	.id_table =         stk8ba50_i2c_id,
548884ca456STiberiu Breana };
549884ca456STiberiu Breana 
550884ca456STiberiu Breana module_i2c_driver(stk8ba50_driver);
551884ca456STiberiu Breana 
552884ca456STiberiu Breana MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>");
553884ca456STiberiu Breana MODULE_DESCRIPTION("STK8BA50 3-Axis Accelerometer driver");
554884ca456STiberiu Breana MODULE_LICENSE("GPL v2");
555