xref: /OK3568_Linux_fs/kernel/drivers/iio/dummy/iio_simple_dummy.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2011 Jonathan Cameron
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * A reference industrial I/O driver to illustrate the functionality available.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * There are numerous real drivers to illustrate the finer points.
8*4882a593Smuzhiyun  * The purpose of this driver is to provide a driver with far more comments
9*4882a593Smuzhiyun  * and explanatory notes than any 'real' driver would have.
10*4882a593Smuzhiyun  * Anyone starting out writing an IIO driver should first make sure they
11*4882a593Smuzhiyun  * understand all of this driver except those bits specifically marked
12*4882a593Smuzhiyun  * as being present to allow us to 'fake' the presence of hardware.
13*4882a593Smuzhiyun  */
14*4882a593Smuzhiyun #include <linux/kernel.h>
15*4882a593Smuzhiyun #include <linux/slab.h>
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/string.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <linux/iio/iio.h>
20*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
21*4882a593Smuzhiyun #include <linux/iio/events.h>
22*4882a593Smuzhiyun #include <linux/iio/buffer.h>
23*4882a593Smuzhiyun #include <linux/iio/sw_device.h>
24*4882a593Smuzhiyun #include "iio_simple_dummy.h"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun static const struct config_item_type iio_dummy_type = {
27*4882a593Smuzhiyun 	.ct_owner = THIS_MODULE,
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /**
31*4882a593Smuzhiyun  * struct iio_dummy_accel_calibscale - realworld to register mapping
32*4882a593Smuzhiyun  * @val: first value in read_raw - here integer part.
33*4882a593Smuzhiyun  * @val2: second value in read_raw etc - here micro part.
34*4882a593Smuzhiyun  * @regval: register value - magic device specific numbers.
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun struct iio_dummy_accel_calibscale {
37*4882a593Smuzhiyun 	int val;
38*4882a593Smuzhiyun 	int val2;
39*4882a593Smuzhiyun 	int regval; /* what would be written to hardware */
40*4882a593Smuzhiyun };
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun static const struct iio_dummy_accel_calibscale dummy_scales[] = {
43*4882a593Smuzhiyun 	{ 0, 100, 0x8 }, /* 0.000100 */
44*4882a593Smuzhiyun 	{ 0, 133, 0x7 }, /* 0.000133 */
45*4882a593Smuzhiyun 	{ 733, 13, 0x9 }, /* 733.000013 */
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /*
51*4882a593Smuzhiyun  * simple event - triggered when value rises above
52*4882a593Smuzhiyun  * a threshold
53*4882a593Smuzhiyun  */
54*4882a593Smuzhiyun static const struct iio_event_spec iio_dummy_event = {
55*4882a593Smuzhiyun 	.type = IIO_EV_TYPE_THRESH,
56*4882a593Smuzhiyun 	.dir = IIO_EV_DIR_RISING,
57*4882a593Smuzhiyun 	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun  * simple step detect event - triggered when a step is detected
62*4882a593Smuzhiyun  */
63*4882a593Smuzhiyun static const struct iio_event_spec step_detect_event = {
64*4882a593Smuzhiyun 	.type = IIO_EV_TYPE_CHANGE,
65*4882a593Smuzhiyun 	.dir = IIO_EV_DIR_NONE,
66*4882a593Smuzhiyun 	.mask_separate = BIT(IIO_EV_INFO_ENABLE),
67*4882a593Smuzhiyun };
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /*
70*4882a593Smuzhiyun  * simple transition event - triggered when the reported running confidence
71*4882a593Smuzhiyun  * value rises above a threshold value
72*4882a593Smuzhiyun  */
73*4882a593Smuzhiyun static const struct iio_event_spec iio_running_event = {
74*4882a593Smuzhiyun 	.type = IIO_EV_TYPE_THRESH,
75*4882a593Smuzhiyun 	.dir = IIO_EV_DIR_RISING,
76*4882a593Smuzhiyun 	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
77*4882a593Smuzhiyun };
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun  * simple transition event - triggered when the reported walking confidence
81*4882a593Smuzhiyun  * value falls under a threshold value
82*4882a593Smuzhiyun  */
83*4882a593Smuzhiyun static const struct iio_event_spec iio_walking_event = {
84*4882a593Smuzhiyun 	.type = IIO_EV_TYPE_THRESH,
85*4882a593Smuzhiyun 	.dir = IIO_EV_DIR_FALLING,
86*4882a593Smuzhiyun 	.mask_separate = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_ENABLE),
87*4882a593Smuzhiyun };
88*4882a593Smuzhiyun #endif
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun /*
91*4882a593Smuzhiyun  * iio_dummy_channels - Description of available channels
92*4882a593Smuzhiyun  *
93*4882a593Smuzhiyun  * This array of structures tells the IIO core about what the device
94*4882a593Smuzhiyun  * actually provides for a given channel.
95*4882a593Smuzhiyun  */
96*4882a593Smuzhiyun static const struct iio_chan_spec iio_dummy_channels[] = {
97*4882a593Smuzhiyun 	/* indexed ADC channel in_voltage0_raw etc */
98*4882a593Smuzhiyun 	{
99*4882a593Smuzhiyun 		.type = IIO_VOLTAGE,
100*4882a593Smuzhiyun 		/* Channel has a numeric index of 0 */
101*4882a593Smuzhiyun 		.indexed = 1,
102*4882a593Smuzhiyun 		.channel = 0,
103*4882a593Smuzhiyun 		/* What other information is available? */
104*4882a593Smuzhiyun 		.info_mask_separate =
105*4882a593Smuzhiyun 		/*
106*4882a593Smuzhiyun 		 * in_voltage0_raw
107*4882a593Smuzhiyun 		 * Raw (unscaled no bias removal etc) measurement
108*4882a593Smuzhiyun 		 * from the device.
109*4882a593Smuzhiyun 		 */
110*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_RAW) |
111*4882a593Smuzhiyun 		/*
112*4882a593Smuzhiyun 		 * in_voltage0_offset
113*4882a593Smuzhiyun 		 * Offset for userspace to apply prior to scale
114*4882a593Smuzhiyun 		 * when converting to standard units (microvolts)
115*4882a593Smuzhiyun 		 */
116*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_OFFSET) |
117*4882a593Smuzhiyun 		/*
118*4882a593Smuzhiyun 		 * in_voltage0_scale
119*4882a593Smuzhiyun 		 * Multipler for userspace to apply post offset
120*4882a593Smuzhiyun 		 * when converting to standard units (microvolts)
121*4882a593Smuzhiyun 		 */
122*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_SCALE),
123*4882a593Smuzhiyun 		/*
124*4882a593Smuzhiyun 		 * sampling_frequency
125*4882a593Smuzhiyun 		 * The frequency in Hz at which the channels are sampled
126*4882a593Smuzhiyun 		 */
127*4882a593Smuzhiyun 		.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
128*4882a593Smuzhiyun 		/* The ordering of elements in the buffer via an enum */
129*4882a593Smuzhiyun 		.scan_index = DUMMY_INDEX_VOLTAGE_0,
130*4882a593Smuzhiyun 		.scan_type = { /* Description of storage in buffer */
131*4882a593Smuzhiyun 			.sign = 'u', /* unsigned */
132*4882a593Smuzhiyun 			.realbits = 13, /* 13 bits */
133*4882a593Smuzhiyun 			.storagebits = 16, /* 16 bits used for storage */
134*4882a593Smuzhiyun 			.shift = 0, /* zero shift */
135*4882a593Smuzhiyun 		},
136*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
137*4882a593Smuzhiyun 		.event_spec = &iio_dummy_event,
138*4882a593Smuzhiyun 		.num_event_specs = 1,
139*4882a593Smuzhiyun #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
140*4882a593Smuzhiyun 	},
141*4882a593Smuzhiyun 	/* Differential ADC channel in_voltage1-voltage2_raw etc*/
142*4882a593Smuzhiyun 	{
143*4882a593Smuzhiyun 		.type = IIO_VOLTAGE,
144*4882a593Smuzhiyun 		.differential = 1,
145*4882a593Smuzhiyun 		/*
146*4882a593Smuzhiyun 		 * Indexing for differential channels uses channel
147*4882a593Smuzhiyun 		 * for the positive part, channel2 for the negative.
148*4882a593Smuzhiyun 		 */
149*4882a593Smuzhiyun 		.indexed = 1,
150*4882a593Smuzhiyun 		.channel = 1,
151*4882a593Smuzhiyun 		.channel2 = 2,
152*4882a593Smuzhiyun 		/*
153*4882a593Smuzhiyun 		 * in_voltage1-voltage2_raw
154*4882a593Smuzhiyun 		 * Raw (unscaled no bias removal etc) measurement
155*4882a593Smuzhiyun 		 * from the device.
156*4882a593Smuzhiyun 		 */
157*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
158*4882a593Smuzhiyun 		/*
159*4882a593Smuzhiyun 		 * in_voltage-voltage_scale
160*4882a593Smuzhiyun 		 * Shared version of scale - shared by differential
161*4882a593Smuzhiyun 		 * input channels of type IIO_VOLTAGE.
162*4882a593Smuzhiyun 		 */
163*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
164*4882a593Smuzhiyun 		/*
165*4882a593Smuzhiyun 		 * sampling_frequency
166*4882a593Smuzhiyun 		 * The frequency in Hz at which the channels are sampled
167*4882a593Smuzhiyun 		 */
168*4882a593Smuzhiyun 		.scan_index = DUMMY_INDEX_DIFFVOLTAGE_1M2,
169*4882a593Smuzhiyun 		.scan_type = { /* Description of storage in buffer */
170*4882a593Smuzhiyun 			.sign = 's', /* signed */
171*4882a593Smuzhiyun 			.realbits = 12, /* 12 bits */
172*4882a593Smuzhiyun 			.storagebits = 16, /* 16 bits used for storage */
173*4882a593Smuzhiyun 			.shift = 0, /* zero shift */
174*4882a593Smuzhiyun 		},
175*4882a593Smuzhiyun 	},
176*4882a593Smuzhiyun 	/* Differential ADC channel in_voltage3-voltage4_raw etc*/
177*4882a593Smuzhiyun 	{
178*4882a593Smuzhiyun 		.type = IIO_VOLTAGE,
179*4882a593Smuzhiyun 		.differential = 1,
180*4882a593Smuzhiyun 		.indexed = 1,
181*4882a593Smuzhiyun 		.channel = 3,
182*4882a593Smuzhiyun 		.channel2 = 4,
183*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
184*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
185*4882a593Smuzhiyun 		.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
186*4882a593Smuzhiyun 		.scan_index = DUMMY_INDEX_DIFFVOLTAGE_3M4,
187*4882a593Smuzhiyun 		.scan_type = {
188*4882a593Smuzhiyun 			.sign = 's',
189*4882a593Smuzhiyun 			.realbits = 11,
190*4882a593Smuzhiyun 			.storagebits = 16,
191*4882a593Smuzhiyun 			.shift = 0,
192*4882a593Smuzhiyun 		},
193*4882a593Smuzhiyun 	},
194*4882a593Smuzhiyun 	/*
195*4882a593Smuzhiyun 	 * 'modified' (i.e. axis specified) acceleration channel
196*4882a593Smuzhiyun 	 * in_accel_z_raw
197*4882a593Smuzhiyun 	 */
198*4882a593Smuzhiyun 	{
199*4882a593Smuzhiyun 		.type = IIO_ACCEL,
200*4882a593Smuzhiyun 		.modified = 1,
201*4882a593Smuzhiyun 		/* Channel 2 is use for modifiers */
202*4882a593Smuzhiyun 		.channel2 = IIO_MOD_X,
203*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
204*4882a593Smuzhiyun 		/*
205*4882a593Smuzhiyun 		 * Internal bias and gain correction values. Applied
206*4882a593Smuzhiyun 		 * by the hardware or driver prior to userspace
207*4882a593Smuzhiyun 		 * seeing the readings. Typically part of hardware
208*4882a593Smuzhiyun 		 * calibration.
209*4882a593Smuzhiyun 		 */
210*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_CALIBSCALE) |
211*4882a593Smuzhiyun 		BIT(IIO_CHAN_INFO_CALIBBIAS),
212*4882a593Smuzhiyun 		.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
213*4882a593Smuzhiyun 		.scan_index = DUMMY_INDEX_ACCELX,
214*4882a593Smuzhiyun 		.scan_type = { /* Description of storage in buffer */
215*4882a593Smuzhiyun 			.sign = 's', /* signed */
216*4882a593Smuzhiyun 			.realbits = 16, /* 16 bits */
217*4882a593Smuzhiyun 			.storagebits = 16, /* 16 bits used for storage */
218*4882a593Smuzhiyun 			.shift = 0, /* zero shift */
219*4882a593Smuzhiyun 		},
220*4882a593Smuzhiyun 	},
221*4882a593Smuzhiyun 	/*
222*4882a593Smuzhiyun 	 * Convenience macro for timestamps. 4 is the index in
223*4882a593Smuzhiyun 	 * the buffer.
224*4882a593Smuzhiyun 	 */
225*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(4),
226*4882a593Smuzhiyun 	/* DAC channel out_voltage0_raw */
227*4882a593Smuzhiyun 	{
228*4882a593Smuzhiyun 		.type = IIO_VOLTAGE,
229*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
230*4882a593Smuzhiyun 		.scan_index = -1, /* No buffer support */
231*4882a593Smuzhiyun 		.output = 1,
232*4882a593Smuzhiyun 		.indexed = 1,
233*4882a593Smuzhiyun 		.channel = 0,
234*4882a593Smuzhiyun 	},
235*4882a593Smuzhiyun 	{
236*4882a593Smuzhiyun 		.type = IIO_STEPS,
237*4882a593Smuzhiyun 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_ENABLE) |
238*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_CALIBHEIGHT),
239*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
240*4882a593Smuzhiyun 		.scan_index = -1, /* No buffer support */
241*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
242*4882a593Smuzhiyun 		.event_spec = &step_detect_event,
243*4882a593Smuzhiyun 		.num_event_specs = 1,
244*4882a593Smuzhiyun #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
245*4882a593Smuzhiyun 	},
246*4882a593Smuzhiyun 	{
247*4882a593Smuzhiyun 		.type = IIO_ACTIVITY,
248*4882a593Smuzhiyun 		.modified = 1,
249*4882a593Smuzhiyun 		.channel2 = IIO_MOD_RUNNING,
250*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
251*4882a593Smuzhiyun 		.scan_index = -1, /* No buffer support */
252*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
253*4882a593Smuzhiyun 		.event_spec = &iio_running_event,
254*4882a593Smuzhiyun 		.num_event_specs = 1,
255*4882a593Smuzhiyun #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
256*4882a593Smuzhiyun 	},
257*4882a593Smuzhiyun 	{
258*4882a593Smuzhiyun 		.type = IIO_ACTIVITY,
259*4882a593Smuzhiyun 		.modified = 1,
260*4882a593Smuzhiyun 		.channel2 = IIO_MOD_WALKING,
261*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
262*4882a593Smuzhiyun 		.scan_index = -1, /* No buffer support */
263*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
264*4882a593Smuzhiyun 		.event_spec = &iio_walking_event,
265*4882a593Smuzhiyun 		.num_event_specs = 1,
266*4882a593Smuzhiyun #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
267*4882a593Smuzhiyun 	},
268*4882a593Smuzhiyun };
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun /**
271*4882a593Smuzhiyun  * iio_dummy_read_raw() - data read function.
272*4882a593Smuzhiyun  * @indio_dev:	the struct iio_dev associated with this device instance
273*4882a593Smuzhiyun  * @chan:	the channel whose data is to be read
274*4882a593Smuzhiyun  * @val:	first element of returned value (typically INT)
275*4882a593Smuzhiyun  * @val2:	second element of returned value (typically MICRO)
276*4882a593Smuzhiyun  * @mask:	what we actually want to read as per the info_mask_*
277*4882a593Smuzhiyun  *		in iio_chan_spec.
278*4882a593Smuzhiyun  */
iio_dummy_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)279*4882a593Smuzhiyun static int iio_dummy_read_raw(struct iio_dev *indio_dev,
280*4882a593Smuzhiyun 			      struct iio_chan_spec const *chan,
281*4882a593Smuzhiyun 			      int *val,
282*4882a593Smuzhiyun 			      int *val2,
283*4882a593Smuzhiyun 			      long mask)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun 	struct iio_dummy_state *st = iio_priv(indio_dev);
286*4882a593Smuzhiyun 	int ret = -EINVAL;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	mutex_lock(&st->lock);
289*4882a593Smuzhiyun 	switch (mask) {
290*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW: /* magic value - channel value read */
291*4882a593Smuzhiyun 		switch (chan->type) {
292*4882a593Smuzhiyun 		case IIO_VOLTAGE:
293*4882a593Smuzhiyun 			if (chan->output) {
294*4882a593Smuzhiyun 				/* Set integer part to cached value */
295*4882a593Smuzhiyun 				*val = st->dac_val;
296*4882a593Smuzhiyun 				ret = IIO_VAL_INT;
297*4882a593Smuzhiyun 			} else if (chan->differential) {
298*4882a593Smuzhiyun 				if (chan->channel == 1)
299*4882a593Smuzhiyun 					*val = st->differential_adc_val[0];
300*4882a593Smuzhiyun 				else
301*4882a593Smuzhiyun 					*val = st->differential_adc_val[1];
302*4882a593Smuzhiyun 				ret = IIO_VAL_INT;
303*4882a593Smuzhiyun 			} else {
304*4882a593Smuzhiyun 				*val = st->single_ended_adc_val;
305*4882a593Smuzhiyun 				ret = IIO_VAL_INT;
306*4882a593Smuzhiyun 			}
307*4882a593Smuzhiyun 			break;
308*4882a593Smuzhiyun 		case IIO_ACCEL:
309*4882a593Smuzhiyun 			*val = st->accel_val;
310*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
311*4882a593Smuzhiyun 			break;
312*4882a593Smuzhiyun 		default:
313*4882a593Smuzhiyun 			break;
314*4882a593Smuzhiyun 		}
315*4882a593Smuzhiyun 		break;
316*4882a593Smuzhiyun 	case IIO_CHAN_INFO_PROCESSED:
317*4882a593Smuzhiyun 		switch (chan->type) {
318*4882a593Smuzhiyun 		case IIO_STEPS:
319*4882a593Smuzhiyun 			*val = st->steps;
320*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
321*4882a593Smuzhiyun 			break;
322*4882a593Smuzhiyun 		case IIO_ACTIVITY:
323*4882a593Smuzhiyun 			switch (chan->channel2) {
324*4882a593Smuzhiyun 			case IIO_MOD_RUNNING:
325*4882a593Smuzhiyun 				*val = st->activity_running;
326*4882a593Smuzhiyun 				ret = IIO_VAL_INT;
327*4882a593Smuzhiyun 				break;
328*4882a593Smuzhiyun 			case IIO_MOD_WALKING:
329*4882a593Smuzhiyun 				*val = st->activity_walking;
330*4882a593Smuzhiyun 				ret = IIO_VAL_INT;
331*4882a593Smuzhiyun 				break;
332*4882a593Smuzhiyun 			default:
333*4882a593Smuzhiyun 				break;
334*4882a593Smuzhiyun 			}
335*4882a593Smuzhiyun 			break;
336*4882a593Smuzhiyun 		default:
337*4882a593Smuzhiyun 			break;
338*4882a593Smuzhiyun 		}
339*4882a593Smuzhiyun 		break;
340*4882a593Smuzhiyun 	case IIO_CHAN_INFO_OFFSET:
341*4882a593Smuzhiyun 		/* only single ended adc -> 7 */
342*4882a593Smuzhiyun 		*val = 7;
343*4882a593Smuzhiyun 		ret = IIO_VAL_INT;
344*4882a593Smuzhiyun 		break;
345*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
346*4882a593Smuzhiyun 		switch (chan->type) {
347*4882a593Smuzhiyun 		case IIO_VOLTAGE:
348*4882a593Smuzhiyun 			switch (chan->differential) {
349*4882a593Smuzhiyun 			case 0:
350*4882a593Smuzhiyun 				/* only single ended adc -> 0.001333 */
351*4882a593Smuzhiyun 				*val = 0;
352*4882a593Smuzhiyun 				*val2 = 1333;
353*4882a593Smuzhiyun 				ret = IIO_VAL_INT_PLUS_MICRO;
354*4882a593Smuzhiyun 				break;
355*4882a593Smuzhiyun 			case 1:
356*4882a593Smuzhiyun 				/* all differential adc -> 0.000001344 */
357*4882a593Smuzhiyun 				*val = 0;
358*4882a593Smuzhiyun 				*val2 = 1344;
359*4882a593Smuzhiyun 				ret = IIO_VAL_INT_PLUS_NANO;
360*4882a593Smuzhiyun 			}
361*4882a593Smuzhiyun 			break;
362*4882a593Smuzhiyun 		default:
363*4882a593Smuzhiyun 			break;
364*4882a593Smuzhiyun 		}
365*4882a593Smuzhiyun 		break;
366*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBBIAS:
367*4882a593Smuzhiyun 		/* only the acceleration axis - read from cache */
368*4882a593Smuzhiyun 		*val = st->accel_calibbias;
369*4882a593Smuzhiyun 		ret = IIO_VAL_INT;
370*4882a593Smuzhiyun 		break;
371*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBSCALE:
372*4882a593Smuzhiyun 		*val = st->accel_calibscale->val;
373*4882a593Smuzhiyun 		*val2 = st->accel_calibscale->val2;
374*4882a593Smuzhiyun 		ret = IIO_VAL_INT_PLUS_MICRO;
375*4882a593Smuzhiyun 		break;
376*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SAMP_FREQ:
377*4882a593Smuzhiyun 		*val = 3;
378*4882a593Smuzhiyun 		*val2 = 33;
379*4882a593Smuzhiyun 		ret = IIO_VAL_INT_PLUS_NANO;
380*4882a593Smuzhiyun 		break;
381*4882a593Smuzhiyun 	case IIO_CHAN_INFO_ENABLE:
382*4882a593Smuzhiyun 		switch (chan->type) {
383*4882a593Smuzhiyun 		case IIO_STEPS:
384*4882a593Smuzhiyun 			*val = st->steps_enabled;
385*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
386*4882a593Smuzhiyun 			break;
387*4882a593Smuzhiyun 		default:
388*4882a593Smuzhiyun 			break;
389*4882a593Smuzhiyun 		}
390*4882a593Smuzhiyun 		break;
391*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBHEIGHT:
392*4882a593Smuzhiyun 		switch (chan->type) {
393*4882a593Smuzhiyun 		case IIO_STEPS:
394*4882a593Smuzhiyun 			*val = st->height;
395*4882a593Smuzhiyun 			ret = IIO_VAL_INT;
396*4882a593Smuzhiyun 			break;
397*4882a593Smuzhiyun 		default:
398*4882a593Smuzhiyun 			break;
399*4882a593Smuzhiyun 		}
400*4882a593Smuzhiyun 		break;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 	default:
403*4882a593Smuzhiyun 		break;
404*4882a593Smuzhiyun 	}
405*4882a593Smuzhiyun 	mutex_unlock(&st->lock);
406*4882a593Smuzhiyun 	return ret;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun /**
410*4882a593Smuzhiyun  * iio_dummy_write_raw() - data write function.
411*4882a593Smuzhiyun  * @indio_dev:	the struct iio_dev associated with this device instance
412*4882a593Smuzhiyun  * @chan:	the channel whose data is to be written
413*4882a593Smuzhiyun  * @val:	first element of value to set (typically INT)
414*4882a593Smuzhiyun  * @val2:	second element of value to set (typically MICRO)
415*4882a593Smuzhiyun  * @mask:	what we actually want to write as per the info_mask_*
416*4882a593Smuzhiyun  *		in iio_chan_spec.
417*4882a593Smuzhiyun  *
418*4882a593Smuzhiyun  * Note that all raw writes are assumed IIO_VAL_INT and info mask elements
419*4882a593Smuzhiyun  * are assumed to be IIO_INT_PLUS_MICRO unless the callback write_raw_get_fmt
420*4882a593Smuzhiyun  * in struct iio_info is provided by the driver.
421*4882a593Smuzhiyun  */
iio_dummy_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)422*4882a593Smuzhiyun static int iio_dummy_write_raw(struct iio_dev *indio_dev,
423*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
424*4882a593Smuzhiyun 			       int val,
425*4882a593Smuzhiyun 			       int val2,
426*4882a593Smuzhiyun 			       long mask)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun 	int i;
429*4882a593Smuzhiyun 	int ret = 0;
430*4882a593Smuzhiyun 	struct iio_dummy_state *st = iio_priv(indio_dev);
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun 	switch (mask) {
433*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
434*4882a593Smuzhiyun 		switch (chan->type) {
435*4882a593Smuzhiyun 		case IIO_VOLTAGE:
436*4882a593Smuzhiyun 			if (chan->output == 0)
437*4882a593Smuzhiyun 				return -EINVAL;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 			/* Locking not required as writing single value */
440*4882a593Smuzhiyun 			mutex_lock(&st->lock);
441*4882a593Smuzhiyun 			st->dac_val = val;
442*4882a593Smuzhiyun 			mutex_unlock(&st->lock);
443*4882a593Smuzhiyun 			return 0;
444*4882a593Smuzhiyun 		default:
445*4882a593Smuzhiyun 			return -EINVAL;
446*4882a593Smuzhiyun 		}
447*4882a593Smuzhiyun 	case IIO_CHAN_INFO_PROCESSED:
448*4882a593Smuzhiyun 		switch (chan->type) {
449*4882a593Smuzhiyun 		case IIO_STEPS:
450*4882a593Smuzhiyun 			mutex_lock(&st->lock);
451*4882a593Smuzhiyun 			st->steps = val;
452*4882a593Smuzhiyun 			mutex_unlock(&st->lock);
453*4882a593Smuzhiyun 			return 0;
454*4882a593Smuzhiyun 		case IIO_ACTIVITY:
455*4882a593Smuzhiyun 			if (val < 0)
456*4882a593Smuzhiyun 				val = 0;
457*4882a593Smuzhiyun 			if (val > 100)
458*4882a593Smuzhiyun 				val = 100;
459*4882a593Smuzhiyun 			switch (chan->channel2) {
460*4882a593Smuzhiyun 			case IIO_MOD_RUNNING:
461*4882a593Smuzhiyun 				st->activity_running = val;
462*4882a593Smuzhiyun 				return 0;
463*4882a593Smuzhiyun 			case IIO_MOD_WALKING:
464*4882a593Smuzhiyun 				st->activity_walking = val;
465*4882a593Smuzhiyun 				return 0;
466*4882a593Smuzhiyun 			default:
467*4882a593Smuzhiyun 				return -EINVAL;
468*4882a593Smuzhiyun 			}
469*4882a593Smuzhiyun 			break;
470*4882a593Smuzhiyun 		default:
471*4882a593Smuzhiyun 			return -EINVAL;
472*4882a593Smuzhiyun 		}
473*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBSCALE:
474*4882a593Smuzhiyun 		mutex_lock(&st->lock);
475*4882a593Smuzhiyun 		/* Compare against table - hard matching here */
476*4882a593Smuzhiyun 		for (i = 0; i < ARRAY_SIZE(dummy_scales); i++)
477*4882a593Smuzhiyun 			if (val == dummy_scales[i].val &&
478*4882a593Smuzhiyun 			    val2 == dummy_scales[i].val2)
479*4882a593Smuzhiyun 				break;
480*4882a593Smuzhiyun 		if (i == ARRAY_SIZE(dummy_scales))
481*4882a593Smuzhiyun 			ret = -EINVAL;
482*4882a593Smuzhiyun 		else
483*4882a593Smuzhiyun 			st->accel_calibscale = &dummy_scales[i];
484*4882a593Smuzhiyun 		mutex_unlock(&st->lock);
485*4882a593Smuzhiyun 		return ret;
486*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBBIAS:
487*4882a593Smuzhiyun 		mutex_lock(&st->lock);
488*4882a593Smuzhiyun 		st->accel_calibbias = val;
489*4882a593Smuzhiyun 		mutex_unlock(&st->lock);
490*4882a593Smuzhiyun 		return 0;
491*4882a593Smuzhiyun 	case IIO_CHAN_INFO_ENABLE:
492*4882a593Smuzhiyun 		switch (chan->type) {
493*4882a593Smuzhiyun 		case IIO_STEPS:
494*4882a593Smuzhiyun 			mutex_lock(&st->lock);
495*4882a593Smuzhiyun 			st->steps_enabled = val;
496*4882a593Smuzhiyun 			mutex_unlock(&st->lock);
497*4882a593Smuzhiyun 			return 0;
498*4882a593Smuzhiyun 		default:
499*4882a593Smuzhiyun 			return -EINVAL;
500*4882a593Smuzhiyun 		}
501*4882a593Smuzhiyun 	case IIO_CHAN_INFO_CALIBHEIGHT:
502*4882a593Smuzhiyun 		switch (chan->type) {
503*4882a593Smuzhiyun 		case IIO_STEPS:
504*4882a593Smuzhiyun 			st->height = val;
505*4882a593Smuzhiyun 			return 0;
506*4882a593Smuzhiyun 		default:
507*4882a593Smuzhiyun 			return -EINVAL;
508*4882a593Smuzhiyun 		}
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 	default:
511*4882a593Smuzhiyun 		return -EINVAL;
512*4882a593Smuzhiyun 	}
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun /*
516*4882a593Smuzhiyun  * Device type specific information.
517*4882a593Smuzhiyun  */
518*4882a593Smuzhiyun static const struct iio_info iio_dummy_info = {
519*4882a593Smuzhiyun 	.read_raw = &iio_dummy_read_raw,
520*4882a593Smuzhiyun 	.write_raw = &iio_dummy_write_raw,
521*4882a593Smuzhiyun #ifdef CONFIG_IIO_SIMPLE_DUMMY_EVENTS
522*4882a593Smuzhiyun 	.read_event_config = &iio_simple_dummy_read_event_config,
523*4882a593Smuzhiyun 	.write_event_config = &iio_simple_dummy_write_event_config,
524*4882a593Smuzhiyun 	.read_event_value = &iio_simple_dummy_read_event_value,
525*4882a593Smuzhiyun 	.write_event_value = &iio_simple_dummy_write_event_value,
526*4882a593Smuzhiyun #endif /* CONFIG_IIO_SIMPLE_DUMMY_EVENTS */
527*4882a593Smuzhiyun };
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun /**
530*4882a593Smuzhiyun  * iio_dummy_init_device() - device instance specific init
531*4882a593Smuzhiyun  * @indio_dev: the iio device structure
532*4882a593Smuzhiyun  *
533*4882a593Smuzhiyun  * Most drivers have one of these to set up default values,
534*4882a593Smuzhiyun  * reset the device to known state etc.
535*4882a593Smuzhiyun  */
iio_dummy_init_device(struct iio_dev * indio_dev)536*4882a593Smuzhiyun static int iio_dummy_init_device(struct iio_dev *indio_dev)
537*4882a593Smuzhiyun {
538*4882a593Smuzhiyun 	struct iio_dummy_state *st = iio_priv(indio_dev);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	st->dac_val = 0;
541*4882a593Smuzhiyun 	st->single_ended_adc_val = 73;
542*4882a593Smuzhiyun 	st->differential_adc_val[0] = 33;
543*4882a593Smuzhiyun 	st->differential_adc_val[1] = -34;
544*4882a593Smuzhiyun 	st->accel_val = 34;
545*4882a593Smuzhiyun 	st->accel_calibbias = -7;
546*4882a593Smuzhiyun 	st->accel_calibscale = &dummy_scales[0];
547*4882a593Smuzhiyun 	st->steps = 47;
548*4882a593Smuzhiyun 	st->activity_running = 98;
549*4882a593Smuzhiyun 	st->activity_walking = 4;
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	return 0;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun /**
555*4882a593Smuzhiyun  * iio_dummy_probe() - device instance probe
556*4882a593Smuzhiyun  * @name: name of this instance.
557*4882a593Smuzhiyun  *
558*4882a593Smuzhiyun  * Arguments are bus type specific.
559*4882a593Smuzhiyun  * I2C: iio_dummy_probe(struct i2c_client *client,
560*4882a593Smuzhiyun  *                      const struct i2c_device_id *id)
561*4882a593Smuzhiyun  * SPI: iio_dummy_probe(struct spi_device *spi)
562*4882a593Smuzhiyun  */
iio_dummy_probe(const char * name)563*4882a593Smuzhiyun static struct iio_sw_device *iio_dummy_probe(const char *name)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun 	int ret;
566*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
567*4882a593Smuzhiyun 	struct iio_dummy_state *st;
568*4882a593Smuzhiyun 	struct iio_sw_device *swd;
569*4882a593Smuzhiyun 	struct device *parent = NULL;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	/*
572*4882a593Smuzhiyun 	 * With hardware: Set the parent device.
573*4882a593Smuzhiyun 	 * parent = &spi->dev;
574*4882a593Smuzhiyun 	 * parent = &client->dev;
575*4882a593Smuzhiyun 	 */
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	swd = kzalloc(sizeof(*swd), GFP_KERNEL);
578*4882a593Smuzhiyun 	if (!swd)
579*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 	/*
582*4882a593Smuzhiyun 	 * Allocate an IIO device.
583*4882a593Smuzhiyun 	 *
584*4882a593Smuzhiyun 	 * This structure contains all generic state
585*4882a593Smuzhiyun 	 * information about the device instance.
586*4882a593Smuzhiyun 	 * It also has a region (accessed by iio_priv()
587*4882a593Smuzhiyun 	 * for chip specific state information.
588*4882a593Smuzhiyun 	 */
589*4882a593Smuzhiyun 	indio_dev = iio_device_alloc(parent, sizeof(*st));
590*4882a593Smuzhiyun 	if (!indio_dev) {
591*4882a593Smuzhiyun 		ret = -ENOMEM;
592*4882a593Smuzhiyun 		goto error_free_swd;
593*4882a593Smuzhiyun 	}
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	st = iio_priv(indio_dev);
596*4882a593Smuzhiyun 	mutex_init(&st->lock);
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	iio_dummy_init_device(indio_dev);
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	 /*
601*4882a593Smuzhiyun 	 * Make the iio_dev struct available to remove function.
602*4882a593Smuzhiyun 	 * Bus equivalents
603*4882a593Smuzhiyun 	 * i2c_set_clientdata(client, indio_dev);
604*4882a593Smuzhiyun 	 * spi_set_drvdata(spi, indio_dev);
605*4882a593Smuzhiyun 	 */
606*4882a593Smuzhiyun 	swd->device = indio_dev;
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	/*
609*4882a593Smuzhiyun 	 * Set the device name.
610*4882a593Smuzhiyun 	 *
611*4882a593Smuzhiyun 	 * This is typically a part number and obtained from the module
612*4882a593Smuzhiyun 	 * id table.
613*4882a593Smuzhiyun 	 * e.g. for i2c and spi:
614*4882a593Smuzhiyun 	 *    indio_dev->name = id->name;
615*4882a593Smuzhiyun 	 *    indio_dev->name = spi_get_device_id(spi)->name;
616*4882a593Smuzhiyun 	 */
617*4882a593Smuzhiyun 	indio_dev->name = kstrdup(name, GFP_KERNEL);
618*4882a593Smuzhiyun 	if (!indio_dev->name) {
619*4882a593Smuzhiyun 		ret = -ENOMEM;
620*4882a593Smuzhiyun 		goto error_free_device;
621*4882a593Smuzhiyun 	}
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	/* Provide description of available channels */
624*4882a593Smuzhiyun 	indio_dev->channels = iio_dummy_channels;
625*4882a593Smuzhiyun 	indio_dev->num_channels = ARRAY_SIZE(iio_dummy_channels);
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 	/*
628*4882a593Smuzhiyun 	 * Provide device type specific interface functions and
629*4882a593Smuzhiyun 	 * constant data.
630*4882a593Smuzhiyun 	 */
631*4882a593Smuzhiyun 	indio_dev->info = &iio_dummy_info;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 	/* Specify that device provides sysfs type interfaces */
634*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	ret = iio_simple_dummy_events_register(indio_dev);
637*4882a593Smuzhiyun 	if (ret < 0)
638*4882a593Smuzhiyun 		goto error_free_name;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun 	ret = iio_simple_dummy_configure_buffer(indio_dev);
641*4882a593Smuzhiyun 	if (ret < 0)
642*4882a593Smuzhiyun 		goto error_unregister_events;
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	ret = iio_device_register(indio_dev);
645*4882a593Smuzhiyun 	if (ret < 0)
646*4882a593Smuzhiyun 		goto error_unconfigure_buffer;
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	iio_swd_group_init_type_name(swd, name, &iio_dummy_type);
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 	return swd;
651*4882a593Smuzhiyun error_unconfigure_buffer:
652*4882a593Smuzhiyun 	iio_simple_dummy_unconfigure_buffer(indio_dev);
653*4882a593Smuzhiyun error_unregister_events:
654*4882a593Smuzhiyun 	iio_simple_dummy_events_unregister(indio_dev);
655*4882a593Smuzhiyun error_free_name:
656*4882a593Smuzhiyun 	kfree(indio_dev->name);
657*4882a593Smuzhiyun error_free_device:
658*4882a593Smuzhiyun 	iio_device_free(indio_dev);
659*4882a593Smuzhiyun error_free_swd:
660*4882a593Smuzhiyun 	kfree(swd);
661*4882a593Smuzhiyun 	return ERR_PTR(ret);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun /**
665*4882a593Smuzhiyun  * iio_dummy_remove() - device instance removal function
666*4882a593Smuzhiyun  * @swd: pointer to software IIO device abstraction
667*4882a593Smuzhiyun  *
668*4882a593Smuzhiyun  * Parameters follow those of iio_dummy_probe for buses.
669*4882a593Smuzhiyun  */
iio_dummy_remove(struct iio_sw_device * swd)670*4882a593Smuzhiyun static int iio_dummy_remove(struct iio_sw_device *swd)
671*4882a593Smuzhiyun {
672*4882a593Smuzhiyun 	/*
673*4882a593Smuzhiyun 	 * Get a pointer to the device instance iio_dev structure
674*4882a593Smuzhiyun 	 * from the bus subsystem. E.g.
675*4882a593Smuzhiyun 	 * struct iio_dev *indio_dev = i2c_get_clientdata(client);
676*4882a593Smuzhiyun 	 * struct iio_dev *indio_dev = spi_get_drvdata(spi);
677*4882a593Smuzhiyun 	 */
678*4882a593Smuzhiyun 	struct iio_dev *indio_dev = swd->device;
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun 	/* Unregister the device */
681*4882a593Smuzhiyun 	iio_device_unregister(indio_dev);
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	/* Device specific code to power down etc */
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun 	/* Buffered capture related cleanup */
686*4882a593Smuzhiyun 	iio_simple_dummy_unconfigure_buffer(indio_dev);
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	iio_simple_dummy_events_unregister(indio_dev);
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	/* Free all structures */
691*4882a593Smuzhiyun 	kfree(indio_dev->name);
692*4882a593Smuzhiyun 	iio_device_free(indio_dev);
693*4882a593Smuzhiyun 
694*4882a593Smuzhiyun 	return 0;
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun /*
698*4882a593Smuzhiyun  * module_iio_sw_device_driver() -  device driver registration
699*4882a593Smuzhiyun  *
700*4882a593Smuzhiyun  * Varies depending on bus type of the device. As there is no device
701*4882a593Smuzhiyun  * here, call probe directly. For information on device registration
702*4882a593Smuzhiyun  * i2c:
703*4882a593Smuzhiyun  * Documentation/i2c/writing-clients.rst
704*4882a593Smuzhiyun  * spi:
705*4882a593Smuzhiyun  * Documentation/spi/spi-summary.rst
706*4882a593Smuzhiyun  */
707*4882a593Smuzhiyun static const struct iio_sw_device_ops iio_dummy_device_ops = {
708*4882a593Smuzhiyun 	.probe = iio_dummy_probe,
709*4882a593Smuzhiyun 	.remove = iio_dummy_remove,
710*4882a593Smuzhiyun };
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun static struct iio_sw_device_type iio_dummy_device = {
713*4882a593Smuzhiyun 	.name = "dummy",
714*4882a593Smuzhiyun 	.owner = THIS_MODULE,
715*4882a593Smuzhiyun 	.ops = &iio_dummy_device_ops,
716*4882a593Smuzhiyun };
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun module_iio_sw_device_driver(iio_dummy_device);
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun MODULE_AUTHOR("Jonathan Cameron <jic23@kernel.org>");
721*4882a593Smuzhiyun MODULE_DESCRIPTION("IIO dummy driver");
722*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
723