xref: /OK3568_Linux_fs/kernel/drivers/iio/light/rpr0521.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * RPR-0521 ROHM Ambient Light and Proximity Sensor
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2015, Intel Corporation.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * IIO driver for RPR-0521RS (7-bit I2C slave address 0x38).
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * TODO: illuminance channel
10*4882a593Smuzhiyun  */
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/init.h>
14*4882a593Smuzhiyun #include <linux/i2c.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/delay.h>
17*4882a593Smuzhiyun #include <linux/acpi.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #include <linux/iio/iio.h>
20*4882a593Smuzhiyun #include <linux/iio/buffer.h>
21*4882a593Smuzhiyun #include <linux/iio/trigger.h>
22*4882a593Smuzhiyun #include <linux/iio/trigger_consumer.h>
23*4882a593Smuzhiyun #include <linux/iio/triggered_buffer.h>
24*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
25*4882a593Smuzhiyun #include <linux/pm_runtime.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define RPR0521_REG_SYSTEM_CTRL		0x40
28*4882a593Smuzhiyun #define RPR0521_REG_MODE_CTRL		0x41
29*4882a593Smuzhiyun #define RPR0521_REG_ALS_CTRL		0x42
30*4882a593Smuzhiyun #define RPR0521_REG_PXS_CTRL		0x43
31*4882a593Smuzhiyun #define RPR0521_REG_PXS_DATA		0x44 /* 16-bit, little endian */
32*4882a593Smuzhiyun #define RPR0521_REG_ALS_DATA0		0x46 /* 16-bit, little endian */
33*4882a593Smuzhiyun #define RPR0521_REG_ALS_DATA1		0x48 /* 16-bit, little endian */
34*4882a593Smuzhiyun #define RPR0521_REG_INTERRUPT		0x4A
35*4882a593Smuzhiyun #define RPR0521_REG_PS_OFFSET_LSB	0x53
36*4882a593Smuzhiyun #define RPR0521_REG_ID			0x92
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #define RPR0521_MODE_ALS_MASK		BIT(7)
39*4882a593Smuzhiyun #define RPR0521_MODE_PXS_MASK		BIT(6)
40*4882a593Smuzhiyun #define RPR0521_MODE_MEAS_TIME_MASK	GENMASK(3, 0)
41*4882a593Smuzhiyun #define RPR0521_ALS_DATA0_GAIN_MASK	GENMASK(5, 4)
42*4882a593Smuzhiyun #define RPR0521_ALS_DATA0_GAIN_SHIFT	4
43*4882a593Smuzhiyun #define RPR0521_ALS_DATA1_GAIN_MASK	GENMASK(3, 2)
44*4882a593Smuzhiyun #define RPR0521_ALS_DATA1_GAIN_SHIFT	2
45*4882a593Smuzhiyun #define RPR0521_PXS_GAIN_MASK		GENMASK(5, 4)
46*4882a593Smuzhiyun #define RPR0521_PXS_GAIN_SHIFT		4
47*4882a593Smuzhiyun #define RPR0521_PXS_PERSISTENCE_MASK	GENMASK(3, 0)
48*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_PS_MASK	BIT(0)
49*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_ALS_MASK	BIT(1)
50*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_REASSERT_MASK	BIT(3)
51*4882a593Smuzhiyun #define RPR0521_INTERRUPT_ALS_INT_STATUS_MASK	BIT(6)
52*4882a593Smuzhiyun #define RPR0521_INTERRUPT_PS_INT_STATUS_MASK	BIT(7)
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define RPR0521_MODE_ALS_ENABLE		BIT(7)
55*4882a593Smuzhiyun #define RPR0521_MODE_ALS_DISABLE	0x00
56*4882a593Smuzhiyun #define RPR0521_MODE_PXS_ENABLE		BIT(6)
57*4882a593Smuzhiyun #define RPR0521_MODE_PXS_DISABLE	0x00
58*4882a593Smuzhiyun #define RPR0521_PXS_PERSISTENCE_DRDY	0x00
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_PS_ENABLE	BIT(0)
61*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_PS_DISABLE	0x00
62*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_ALS_ENABLE	BIT(1)
63*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE	0x00
64*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_REASSERT_ENABLE	BIT(3)
65*4882a593Smuzhiyun #define RPR0521_INTERRUPT_INT_REASSERT_DISABLE	0x00
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define RPR0521_MANUFACT_ID		0xE0
68*4882a593Smuzhiyun #define RPR0521_DEFAULT_MEAS_TIME	0x06 /* ALS - 100ms, PXS - 100ms */
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #define RPR0521_DRV_NAME		"RPR0521"
71*4882a593Smuzhiyun #define RPR0521_IRQ_NAME		"rpr0521_event"
72*4882a593Smuzhiyun #define RPR0521_REGMAP_NAME		"rpr0521_regmap"
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define RPR0521_SLEEP_DELAY_MS	2000
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define RPR0521_ALS_SCALE_AVAIL "0.007812 0.015625 0.5 1"
77*4882a593Smuzhiyun #define RPR0521_PXS_SCALE_AVAIL "0.125 0.5 1"
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun struct rpr0521_gain {
80*4882a593Smuzhiyun 	int scale;
81*4882a593Smuzhiyun 	int uscale;
82*4882a593Smuzhiyun };
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun static const struct rpr0521_gain rpr0521_als_gain[4] = {
85*4882a593Smuzhiyun 	{1, 0},		/* x1 */
86*4882a593Smuzhiyun 	{0, 500000},	/* x2 */
87*4882a593Smuzhiyun 	{0, 15625},	/* x64 */
88*4882a593Smuzhiyun 	{0, 7812},	/* x128 */
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun static const struct rpr0521_gain rpr0521_pxs_gain[3] = {
92*4882a593Smuzhiyun 	{1, 0},		/* x1 */
93*4882a593Smuzhiyun 	{0, 500000},	/* x2 */
94*4882a593Smuzhiyun 	{0, 125000},	/* x4 */
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun enum rpr0521_channel {
98*4882a593Smuzhiyun 	RPR0521_CHAN_PXS,
99*4882a593Smuzhiyun 	RPR0521_CHAN_ALS_DATA0,
100*4882a593Smuzhiyun 	RPR0521_CHAN_ALS_DATA1,
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun struct rpr0521_reg_desc {
104*4882a593Smuzhiyun 	u8 address;
105*4882a593Smuzhiyun 	u8 device_mask;
106*4882a593Smuzhiyun };
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun static const struct rpr0521_reg_desc rpr0521_data_reg[] = {
109*4882a593Smuzhiyun 	[RPR0521_CHAN_PXS]	= {
110*4882a593Smuzhiyun 		.address	= RPR0521_REG_PXS_DATA,
111*4882a593Smuzhiyun 		.device_mask	= RPR0521_MODE_PXS_MASK,
112*4882a593Smuzhiyun 	},
113*4882a593Smuzhiyun 	[RPR0521_CHAN_ALS_DATA0] = {
114*4882a593Smuzhiyun 		.address	= RPR0521_REG_ALS_DATA0,
115*4882a593Smuzhiyun 		.device_mask	= RPR0521_MODE_ALS_MASK,
116*4882a593Smuzhiyun 	},
117*4882a593Smuzhiyun 	[RPR0521_CHAN_ALS_DATA1] = {
118*4882a593Smuzhiyun 		.address	= RPR0521_REG_ALS_DATA1,
119*4882a593Smuzhiyun 		.device_mask	= RPR0521_MODE_ALS_MASK,
120*4882a593Smuzhiyun 	},
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun static const struct rpr0521_gain_info {
124*4882a593Smuzhiyun 	u8 reg;
125*4882a593Smuzhiyun 	u8 mask;
126*4882a593Smuzhiyun 	u8 shift;
127*4882a593Smuzhiyun 	const struct rpr0521_gain *gain;
128*4882a593Smuzhiyun 	int size;
129*4882a593Smuzhiyun } rpr0521_gain[] = {
130*4882a593Smuzhiyun 	[RPR0521_CHAN_PXS] = {
131*4882a593Smuzhiyun 		.reg	= RPR0521_REG_PXS_CTRL,
132*4882a593Smuzhiyun 		.mask	= RPR0521_PXS_GAIN_MASK,
133*4882a593Smuzhiyun 		.shift	= RPR0521_PXS_GAIN_SHIFT,
134*4882a593Smuzhiyun 		.gain	= rpr0521_pxs_gain,
135*4882a593Smuzhiyun 		.size	= ARRAY_SIZE(rpr0521_pxs_gain),
136*4882a593Smuzhiyun 	},
137*4882a593Smuzhiyun 	[RPR0521_CHAN_ALS_DATA0] = {
138*4882a593Smuzhiyun 		.reg	= RPR0521_REG_ALS_CTRL,
139*4882a593Smuzhiyun 		.mask	= RPR0521_ALS_DATA0_GAIN_MASK,
140*4882a593Smuzhiyun 		.shift	= RPR0521_ALS_DATA0_GAIN_SHIFT,
141*4882a593Smuzhiyun 		.gain	= rpr0521_als_gain,
142*4882a593Smuzhiyun 		.size	= ARRAY_SIZE(rpr0521_als_gain),
143*4882a593Smuzhiyun 	},
144*4882a593Smuzhiyun 	[RPR0521_CHAN_ALS_DATA1] = {
145*4882a593Smuzhiyun 		.reg	= RPR0521_REG_ALS_CTRL,
146*4882a593Smuzhiyun 		.mask	= RPR0521_ALS_DATA1_GAIN_MASK,
147*4882a593Smuzhiyun 		.shift	= RPR0521_ALS_DATA1_GAIN_SHIFT,
148*4882a593Smuzhiyun 		.gain	= rpr0521_als_gain,
149*4882a593Smuzhiyun 		.size	= ARRAY_SIZE(rpr0521_als_gain),
150*4882a593Smuzhiyun 	},
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun struct rpr0521_samp_freq {
154*4882a593Smuzhiyun 	int	als_hz;
155*4882a593Smuzhiyun 	int	als_uhz;
156*4882a593Smuzhiyun 	int	pxs_hz;
157*4882a593Smuzhiyun 	int	pxs_uhz;
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun static const struct rpr0521_samp_freq rpr0521_samp_freq_i[13] = {
161*4882a593Smuzhiyun /*	{ALS, PXS},		   W==currently writable option */
162*4882a593Smuzhiyun 	{0, 0, 0, 0},		/* W0000, 0=standby */
163*4882a593Smuzhiyun 	{0, 0, 100, 0},		/*  0001 */
164*4882a593Smuzhiyun 	{0, 0, 25, 0},		/*  0010 */
165*4882a593Smuzhiyun 	{0, 0, 10, 0},		/*  0011 */
166*4882a593Smuzhiyun 	{0, 0, 2, 500000},	/*  0100 */
167*4882a593Smuzhiyun 	{10, 0, 20, 0},		/*  0101 */
168*4882a593Smuzhiyun 	{10, 0, 10, 0},		/* W0110 */
169*4882a593Smuzhiyun 	{10, 0, 2, 500000},	/*  0111 */
170*4882a593Smuzhiyun 	{2, 500000, 20, 0},	/*  1000, measurement 100ms, sleep 300ms */
171*4882a593Smuzhiyun 	{2, 500000, 10, 0},	/*  1001, measurement 100ms, sleep 300ms */
172*4882a593Smuzhiyun 	{2, 500000, 0, 0},	/*  1010, high sensitivity mode */
173*4882a593Smuzhiyun 	{2, 500000, 2, 500000},	/* W1011, high sensitivity mode */
174*4882a593Smuzhiyun 	{20, 0, 20, 0}	/* 1100, ALS_data x 0.5, see specification P.18 */
175*4882a593Smuzhiyun };
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun struct rpr0521_data {
178*4882a593Smuzhiyun 	struct i2c_client *client;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	/* protect device params updates (e.g state, gain) */
181*4882a593Smuzhiyun 	struct mutex lock;
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 	/* device active status */
184*4882a593Smuzhiyun 	bool als_dev_en;
185*4882a593Smuzhiyun 	bool pxs_dev_en;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 	struct iio_trigger *drdy_trigger0;
188*4882a593Smuzhiyun 	s64 irq_timestamp;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	/* optimize runtime pm ops - enable/disable device only if needed */
191*4882a593Smuzhiyun 	bool als_ps_need_en;
192*4882a593Smuzhiyun 	bool pxs_ps_need_en;
193*4882a593Smuzhiyun 	bool als_need_dis;
194*4882a593Smuzhiyun 	bool pxs_need_dis;
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	struct regmap *regmap;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	/*
199*4882a593Smuzhiyun 	 * Ensure correct naturally aligned timestamp.
200*4882a593Smuzhiyun 	 * Note that the read will put garbage data into
201*4882a593Smuzhiyun 	 * the padding but this should not be a problem
202*4882a593Smuzhiyun 	 */
203*4882a593Smuzhiyun 	struct {
204*4882a593Smuzhiyun 		__le16 channels[3];
205*4882a593Smuzhiyun 		u8 garbage;
206*4882a593Smuzhiyun 		s64 ts __aligned(8);
207*4882a593Smuzhiyun 	} scan;
208*4882a593Smuzhiyun };
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun static IIO_CONST_ATTR(in_intensity_scale_available, RPR0521_ALS_SCALE_AVAIL);
211*4882a593Smuzhiyun static IIO_CONST_ATTR(in_proximity_scale_available, RPR0521_PXS_SCALE_AVAIL);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun /*
214*4882a593Smuzhiyun  * Start with easy freq first, whole table of freq combinations is more
215*4882a593Smuzhiyun  * complicated.
216*4882a593Smuzhiyun  */
217*4882a593Smuzhiyun static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("2.5 10");
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun static struct attribute *rpr0521_attributes[] = {
220*4882a593Smuzhiyun 	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
221*4882a593Smuzhiyun 	&iio_const_attr_in_proximity_scale_available.dev_attr.attr,
222*4882a593Smuzhiyun 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
223*4882a593Smuzhiyun 	NULL,
224*4882a593Smuzhiyun };
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun static const struct attribute_group rpr0521_attribute_group = {
227*4882a593Smuzhiyun 	.attrs = rpr0521_attributes,
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun /* Order of the channel data in buffer */
231*4882a593Smuzhiyun enum rpr0521_scan_index_order {
232*4882a593Smuzhiyun 	RPR0521_CHAN_INDEX_PXS,
233*4882a593Smuzhiyun 	RPR0521_CHAN_INDEX_BOTH,
234*4882a593Smuzhiyun 	RPR0521_CHAN_INDEX_IR,
235*4882a593Smuzhiyun };
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun static const unsigned long rpr0521_available_scan_masks[] = {
238*4882a593Smuzhiyun 	BIT(RPR0521_CHAN_INDEX_PXS) | BIT(RPR0521_CHAN_INDEX_BOTH) |
239*4882a593Smuzhiyun 	BIT(RPR0521_CHAN_INDEX_IR),
240*4882a593Smuzhiyun 	0
241*4882a593Smuzhiyun };
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun static const struct iio_chan_spec rpr0521_channels[] = {
244*4882a593Smuzhiyun 	{
245*4882a593Smuzhiyun 		.type = IIO_PROXIMITY,
246*4882a593Smuzhiyun 		.address = RPR0521_CHAN_PXS,
247*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
248*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_OFFSET) |
249*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_SCALE),
250*4882a593Smuzhiyun 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
251*4882a593Smuzhiyun 		.scan_index = RPR0521_CHAN_INDEX_PXS,
252*4882a593Smuzhiyun 		.scan_type = {
253*4882a593Smuzhiyun 			.sign = 'u',
254*4882a593Smuzhiyun 			.realbits = 16,
255*4882a593Smuzhiyun 			.storagebits = 16,
256*4882a593Smuzhiyun 			.endianness = IIO_LE,
257*4882a593Smuzhiyun 		},
258*4882a593Smuzhiyun 	},
259*4882a593Smuzhiyun 	{
260*4882a593Smuzhiyun 		.type = IIO_INTENSITY,
261*4882a593Smuzhiyun 		.modified = 1,
262*4882a593Smuzhiyun 		.address = RPR0521_CHAN_ALS_DATA0,
263*4882a593Smuzhiyun 		.channel2 = IIO_MOD_LIGHT_BOTH,
264*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
265*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_SCALE),
266*4882a593Smuzhiyun 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
267*4882a593Smuzhiyun 		.scan_index = RPR0521_CHAN_INDEX_BOTH,
268*4882a593Smuzhiyun 		.scan_type = {
269*4882a593Smuzhiyun 			.sign = 'u',
270*4882a593Smuzhiyun 			.realbits = 16,
271*4882a593Smuzhiyun 			.storagebits = 16,
272*4882a593Smuzhiyun 			.endianness = IIO_LE,
273*4882a593Smuzhiyun 		},
274*4882a593Smuzhiyun 	},
275*4882a593Smuzhiyun 	{
276*4882a593Smuzhiyun 		.type = IIO_INTENSITY,
277*4882a593Smuzhiyun 		.modified = 1,
278*4882a593Smuzhiyun 		.address = RPR0521_CHAN_ALS_DATA1,
279*4882a593Smuzhiyun 		.channel2 = IIO_MOD_LIGHT_IR,
280*4882a593Smuzhiyun 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
281*4882a593Smuzhiyun 			BIT(IIO_CHAN_INFO_SCALE),
282*4882a593Smuzhiyun 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
283*4882a593Smuzhiyun 		.scan_index = RPR0521_CHAN_INDEX_IR,
284*4882a593Smuzhiyun 		.scan_type = {
285*4882a593Smuzhiyun 			.sign = 'u',
286*4882a593Smuzhiyun 			.realbits = 16,
287*4882a593Smuzhiyun 			.storagebits = 16,
288*4882a593Smuzhiyun 			.endianness = IIO_LE,
289*4882a593Smuzhiyun 		},
290*4882a593Smuzhiyun 	},
291*4882a593Smuzhiyun };
292*4882a593Smuzhiyun 
rpr0521_als_enable(struct rpr0521_data * data,u8 status)293*4882a593Smuzhiyun static int rpr0521_als_enable(struct rpr0521_data *data, u8 status)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	int ret;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
298*4882a593Smuzhiyun 				 RPR0521_MODE_ALS_MASK,
299*4882a593Smuzhiyun 				 status);
300*4882a593Smuzhiyun 	if (ret < 0)
301*4882a593Smuzhiyun 		return ret;
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	if (status & RPR0521_MODE_ALS_MASK)
304*4882a593Smuzhiyun 		data->als_dev_en = true;
305*4882a593Smuzhiyun 	else
306*4882a593Smuzhiyun 		data->als_dev_en = false;
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	return 0;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun 
rpr0521_pxs_enable(struct rpr0521_data * data,u8 status)311*4882a593Smuzhiyun static int rpr0521_pxs_enable(struct rpr0521_data *data, u8 status)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun 	int ret;
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
316*4882a593Smuzhiyun 				 RPR0521_MODE_PXS_MASK,
317*4882a593Smuzhiyun 				 status);
318*4882a593Smuzhiyun 	if (ret < 0)
319*4882a593Smuzhiyun 		return ret;
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	if (status & RPR0521_MODE_PXS_MASK)
322*4882a593Smuzhiyun 		data->pxs_dev_en = true;
323*4882a593Smuzhiyun 	else
324*4882a593Smuzhiyun 		data->pxs_dev_en = false;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	return 0;
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun /**
330*4882a593Smuzhiyun  * rpr0521_set_power_state - handles runtime PM state and sensors enabled status
331*4882a593Smuzhiyun  *
332*4882a593Smuzhiyun  * @data: rpr0521 device private data
333*4882a593Smuzhiyun  * @on: state to be set for devices in @device_mask
334*4882a593Smuzhiyun  * @device_mask: bitmask specifying for which device we need to update @on state
335*4882a593Smuzhiyun  *
336*4882a593Smuzhiyun  * Calls for this function must be balanced so that each ON should have matching
337*4882a593Smuzhiyun  * OFF. Otherwise pm usage_count gets out of sync.
338*4882a593Smuzhiyun  */
rpr0521_set_power_state(struct rpr0521_data * data,bool on,u8 device_mask)339*4882a593Smuzhiyun static int rpr0521_set_power_state(struct rpr0521_data *data, bool on,
340*4882a593Smuzhiyun 				   u8 device_mask)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun #ifdef CONFIG_PM
343*4882a593Smuzhiyun 	int ret;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (device_mask & RPR0521_MODE_ALS_MASK) {
346*4882a593Smuzhiyun 		data->als_ps_need_en = on;
347*4882a593Smuzhiyun 		data->als_need_dis = !on;
348*4882a593Smuzhiyun 	}
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun 	if (device_mask & RPR0521_MODE_PXS_MASK) {
351*4882a593Smuzhiyun 		data->pxs_ps_need_en = on;
352*4882a593Smuzhiyun 		data->pxs_need_dis = !on;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	/*
356*4882a593Smuzhiyun 	 * On: _resume() is called only when we are suspended
357*4882a593Smuzhiyun 	 * Off: _suspend() is called after delay if _resume() is not
358*4882a593Smuzhiyun 	 * called before that.
359*4882a593Smuzhiyun 	 * Note: If either measurement is re-enabled before _suspend(),
360*4882a593Smuzhiyun 	 * both stay enabled until _suspend().
361*4882a593Smuzhiyun 	 */
362*4882a593Smuzhiyun 	if (on) {
363*4882a593Smuzhiyun 		ret = pm_runtime_get_sync(&data->client->dev);
364*4882a593Smuzhiyun 	} else {
365*4882a593Smuzhiyun 		pm_runtime_mark_last_busy(&data->client->dev);
366*4882a593Smuzhiyun 		ret = pm_runtime_put_autosuspend(&data->client->dev);
367*4882a593Smuzhiyun 	}
368*4882a593Smuzhiyun 	if (ret < 0) {
369*4882a593Smuzhiyun 		dev_err(&data->client->dev,
370*4882a593Smuzhiyun 			"Failed: rpr0521_set_power_state for %d, ret %d\n",
371*4882a593Smuzhiyun 			on, ret);
372*4882a593Smuzhiyun 		if (on)
373*4882a593Smuzhiyun 			pm_runtime_put_noidle(&data->client->dev);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		return ret;
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	if (on) {
379*4882a593Smuzhiyun 		/* If _resume() was not called, enable measurement now. */
380*4882a593Smuzhiyun 		if (data->als_ps_need_en) {
381*4882a593Smuzhiyun 			ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
382*4882a593Smuzhiyun 			if (ret)
383*4882a593Smuzhiyun 				return ret;
384*4882a593Smuzhiyun 			data->als_ps_need_en = false;
385*4882a593Smuzhiyun 		}
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 		if (data->pxs_ps_need_en) {
388*4882a593Smuzhiyun 			ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
389*4882a593Smuzhiyun 			if (ret)
390*4882a593Smuzhiyun 				return ret;
391*4882a593Smuzhiyun 			data->pxs_ps_need_en = false;
392*4882a593Smuzhiyun 		}
393*4882a593Smuzhiyun 	}
394*4882a593Smuzhiyun #endif
395*4882a593Smuzhiyun 	return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun /* Interrupt register tells if this sensor caused the interrupt or not. */
rpr0521_is_triggered(struct rpr0521_data * data)399*4882a593Smuzhiyun static inline bool rpr0521_is_triggered(struct rpr0521_data *data)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	int ret;
402*4882a593Smuzhiyun 	int reg;
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, &reg);
405*4882a593Smuzhiyun 	if (ret < 0)
406*4882a593Smuzhiyun 		return false;   /* Reg read failed. */
407*4882a593Smuzhiyun 	if (reg &
408*4882a593Smuzhiyun 	    (RPR0521_INTERRUPT_ALS_INT_STATUS_MASK |
409*4882a593Smuzhiyun 	    RPR0521_INTERRUPT_PS_INT_STATUS_MASK))
410*4882a593Smuzhiyun 		return true;
411*4882a593Smuzhiyun 	else
412*4882a593Smuzhiyun 		return false;   /* Int not from this sensor. */
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun /* IRQ to trigger handler */
rpr0521_drdy_irq_handler(int irq,void * private)416*4882a593Smuzhiyun static irqreturn_t rpr0521_drdy_irq_handler(int irq, void *private)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	struct iio_dev *indio_dev = private;
419*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	data->irq_timestamp = iio_get_time_ns(indio_dev);
422*4882a593Smuzhiyun 	/*
423*4882a593Smuzhiyun 	 * We need to wake the thread to read the interrupt reg. It
424*4882a593Smuzhiyun 	 * is not possible to do that here because regmap_read takes a
425*4882a593Smuzhiyun 	 * mutex.
426*4882a593Smuzhiyun 	 */
427*4882a593Smuzhiyun 
428*4882a593Smuzhiyun 	return IRQ_WAKE_THREAD;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
rpr0521_drdy_irq_thread(int irq,void * private)431*4882a593Smuzhiyun static irqreturn_t rpr0521_drdy_irq_thread(int irq, void *private)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun 	struct iio_dev *indio_dev = private;
434*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	if (rpr0521_is_triggered(data)) {
437*4882a593Smuzhiyun 		iio_trigger_poll_chained(data->drdy_trigger0);
438*4882a593Smuzhiyun 		return IRQ_HANDLED;
439*4882a593Smuzhiyun 	}
440*4882a593Smuzhiyun 
441*4882a593Smuzhiyun 	return IRQ_NONE;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
rpr0521_trigger_consumer_store_time(int irq,void * p)444*4882a593Smuzhiyun static irqreturn_t rpr0521_trigger_consumer_store_time(int irq, void *p)
445*4882a593Smuzhiyun {
446*4882a593Smuzhiyun 	struct iio_poll_func *pf = p;
447*4882a593Smuzhiyun 	struct iio_dev *indio_dev = pf->indio_dev;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	/* Other trigger polls store time here. */
450*4882a593Smuzhiyun 	if (!iio_trigger_using_own(indio_dev))
451*4882a593Smuzhiyun 		pf->timestamp = iio_get_time_ns(indio_dev);
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	return IRQ_WAKE_THREAD;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun 
rpr0521_trigger_consumer_handler(int irq,void * p)456*4882a593Smuzhiyun static irqreturn_t rpr0521_trigger_consumer_handler(int irq, void *p)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun 	struct iio_poll_func *pf = p;
459*4882a593Smuzhiyun 	struct iio_dev *indio_dev = pf->indio_dev;
460*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
461*4882a593Smuzhiyun 	int err;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	/* Use irq timestamp when reasonable. */
464*4882a593Smuzhiyun 	if (iio_trigger_using_own(indio_dev) && data->irq_timestamp) {
465*4882a593Smuzhiyun 		pf->timestamp = data->irq_timestamp;
466*4882a593Smuzhiyun 		data->irq_timestamp = 0;
467*4882a593Smuzhiyun 	}
468*4882a593Smuzhiyun 	/* Other chained trigger polls get timestamp only here. */
469*4882a593Smuzhiyun 	if (!pf->timestamp)
470*4882a593Smuzhiyun 		pf->timestamp = iio_get_time_ns(indio_dev);
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun 	err = regmap_bulk_read(data->regmap, RPR0521_REG_PXS_DATA,
473*4882a593Smuzhiyun 		data->scan.channels,
474*4882a593Smuzhiyun 		(3 * 2) + 1);	/* 3 * 16-bit + (discarded) int clear reg. */
475*4882a593Smuzhiyun 	if (!err)
476*4882a593Smuzhiyun 		iio_push_to_buffers_with_timestamp(indio_dev,
477*4882a593Smuzhiyun 						   &data->scan, pf->timestamp);
478*4882a593Smuzhiyun 	else
479*4882a593Smuzhiyun 		dev_err(&data->client->dev,
480*4882a593Smuzhiyun 			"Trigger consumer can't read from sensor.\n");
481*4882a593Smuzhiyun 	pf->timestamp = 0;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	iio_trigger_notify_done(indio_dev->trig);
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	return IRQ_HANDLED;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
rpr0521_write_int_enable(struct rpr0521_data * data)488*4882a593Smuzhiyun static int rpr0521_write_int_enable(struct rpr0521_data *data)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun 	int err;
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	/* Interrupt after each measurement */
493*4882a593Smuzhiyun 	err = regmap_update_bits(data->regmap, RPR0521_REG_PXS_CTRL,
494*4882a593Smuzhiyun 		RPR0521_PXS_PERSISTENCE_MASK,
495*4882a593Smuzhiyun 		RPR0521_PXS_PERSISTENCE_DRDY);
496*4882a593Smuzhiyun 	if (err) {
497*4882a593Smuzhiyun 		dev_err(&data->client->dev, "PS control reg write fail.\n");
498*4882a593Smuzhiyun 		return -EBUSY;
499*4882a593Smuzhiyun 		}
500*4882a593Smuzhiyun 
501*4882a593Smuzhiyun 	/* Ignore latch and mode because of drdy */
502*4882a593Smuzhiyun 	err = regmap_write(data->regmap, RPR0521_REG_INTERRUPT,
503*4882a593Smuzhiyun 		RPR0521_INTERRUPT_INT_REASSERT_DISABLE |
504*4882a593Smuzhiyun 		RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE |
505*4882a593Smuzhiyun 		RPR0521_INTERRUPT_INT_TRIG_PS_ENABLE
506*4882a593Smuzhiyun 		);
507*4882a593Smuzhiyun 	if (err) {
508*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Interrupt setup write fail.\n");
509*4882a593Smuzhiyun 		return -EBUSY;
510*4882a593Smuzhiyun 		}
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	return 0;
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun 
rpr0521_write_int_disable(struct rpr0521_data * data)515*4882a593Smuzhiyun static int rpr0521_write_int_disable(struct rpr0521_data *data)
516*4882a593Smuzhiyun {
517*4882a593Smuzhiyun 	/* Don't care of clearing mode, assert and latch. */
518*4882a593Smuzhiyun 	return regmap_write(data->regmap, RPR0521_REG_INTERRUPT,
519*4882a593Smuzhiyun 				RPR0521_INTERRUPT_INT_TRIG_ALS_DISABLE |
520*4882a593Smuzhiyun 				RPR0521_INTERRUPT_INT_TRIG_PS_DISABLE
521*4882a593Smuzhiyun 				);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun /*
525*4882a593Smuzhiyun  * Trigger producer enable / disable. Note that there will be trigs only when
526*4882a593Smuzhiyun  * measurement data is ready to be read.
527*4882a593Smuzhiyun  */
rpr0521_pxs_drdy_set_state(struct iio_trigger * trigger,bool enable_drdy)528*4882a593Smuzhiyun static int rpr0521_pxs_drdy_set_state(struct iio_trigger *trigger,
529*4882a593Smuzhiyun 	bool enable_drdy)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trigger);
532*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
533*4882a593Smuzhiyun 	int err;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	if (enable_drdy)
536*4882a593Smuzhiyun 		err = rpr0521_write_int_enable(data);
537*4882a593Smuzhiyun 	else
538*4882a593Smuzhiyun 		err = rpr0521_write_int_disable(data);
539*4882a593Smuzhiyun 	if (err)
540*4882a593Smuzhiyun 		dev_err(&data->client->dev, "rpr0521_pxs_drdy_set_state failed\n");
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	return err;
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun static const struct iio_trigger_ops rpr0521_trigger_ops = {
546*4882a593Smuzhiyun 	.set_trigger_state = rpr0521_pxs_drdy_set_state,
547*4882a593Smuzhiyun 	};
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 
rpr0521_buffer_preenable(struct iio_dev * indio_dev)550*4882a593Smuzhiyun static int rpr0521_buffer_preenable(struct iio_dev *indio_dev)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	int err;
553*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	mutex_lock(&data->lock);
556*4882a593Smuzhiyun 	err = rpr0521_set_power_state(data, true,
557*4882a593Smuzhiyun 		(RPR0521_MODE_PXS_MASK | RPR0521_MODE_ALS_MASK));
558*4882a593Smuzhiyun 	mutex_unlock(&data->lock);
559*4882a593Smuzhiyun 	if (err)
560*4882a593Smuzhiyun 		dev_err(&data->client->dev, "_buffer_preenable fail\n");
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun 	return err;
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun 
rpr0521_buffer_postdisable(struct iio_dev * indio_dev)565*4882a593Smuzhiyun static int rpr0521_buffer_postdisable(struct iio_dev *indio_dev)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun 	int err;
568*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 	mutex_lock(&data->lock);
571*4882a593Smuzhiyun 	err = rpr0521_set_power_state(data, false,
572*4882a593Smuzhiyun 		(RPR0521_MODE_PXS_MASK | RPR0521_MODE_ALS_MASK));
573*4882a593Smuzhiyun 	mutex_unlock(&data->lock);
574*4882a593Smuzhiyun 	if (err)
575*4882a593Smuzhiyun 		dev_err(&data->client->dev, "_buffer_postdisable fail\n");
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	return err;
578*4882a593Smuzhiyun }
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun static const struct iio_buffer_setup_ops rpr0521_buffer_setup_ops = {
581*4882a593Smuzhiyun 	.preenable = rpr0521_buffer_preenable,
582*4882a593Smuzhiyun 	.postdisable = rpr0521_buffer_postdisable,
583*4882a593Smuzhiyun };
584*4882a593Smuzhiyun 
rpr0521_get_gain(struct rpr0521_data * data,int chan,int * val,int * val2)585*4882a593Smuzhiyun static int rpr0521_get_gain(struct rpr0521_data *data, int chan,
586*4882a593Smuzhiyun 			    int *val, int *val2)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun 	int ret, reg, idx;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, rpr0521_gain[chan].reg, &reg);
591*4882a593Smuzhiyun 	if (ret < 0)
592*4882a593Smuzhiyun 		return ret;
593*4882a593Smuzhiyun 
594*4882a593Smuzhiyun 	idx = (rpr0521_gain[chan].mask & reg) >> rpr0521_gain[chan].shift;
595*4882a593Smuzhiyun 	*val = rpr0521_gain[chan].gain[idx].scale;
596*4882a593Smuzhiyun 	*val2 = rpr0521_gain[chan].gain[idx].uscale;
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	return 0;
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun 
rpr0521_set_gain(struct rpr0521_data * data,int chan,int val,int val2)601*4882a593Smuzhiyun static int rpr0521_set_gain(struct rpr0521_data *data, int chan,
602*4882a593Smuzhiyun 			    int val, int val2)
603*4882a593Smuzhiyun {
604*4882a593Smuzhiyun 	int i, idx = -EINVAL;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	/* get gain index */
607*4882a593Smuzhiyun 	for (i = 0; i < rpr0521_gain[chan].size; i++)
608*4882a593Smuzhiyun 		if (val == rpr0521_gain[chan].gain[i].scale &&
609*4882a593Smuzhiyun 		    val2 == rpr0521_gain[chan].gain[i].uscale) {
610*4882a593Smuzhiyun 			idx = i;
611*4882a593Smuzhiyun 			break;
612*4882a593Smuzhiyun 		}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	if (idx < 0)
615*4882a593Smuzhiyun 		return idx;
616*4882a593Smuzhiyun 
617*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap, rpr0521_gain[chan].reg,
618*4882a593Smuzhiyun 				  rpr0521_gain[chan].mask,
619*4882a593Smuzhiyun 				  idx << rpr0521_gain[chan].shift);
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun 
rpr0521_read_samp_freq(struct rpr0521_data * data,enum iio_chan_type chan_type,int * val,int * val2)622*4882a593Smuzhiyun static int rpr0521_read_samp_freq(struct rpr0521_data *data,
623*4882a593Smuzhiyun 				enum iio_chan_type chan_type,
624*4882a593Smuzhiyun 			    int *val, int *val2)
625*4882a593Smuzhiyun {
626*4882a593Smuzhiyun 	int reg, ret;
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, RPR0521_REG_MODE_CTRL, &reg);
629*4882a593Smuzhiyun 	if (ret < 0)
630*4882a593Smuzhiyun 		return ret;
631*4882a593Smuzhiyun 
632*4882a593Smuzhiyun 	reg &= RPR0521_MODE_MEAS_TIME_MASK;
633*4882a593Smuzhiyun 	if (reg >= ARRAY_SIZE(rpr0521_samp_freq_i))
634*4882a593Smuzhiyun 		return -EINVAL;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 	switch (chan_type) {
637*4882a593Smuzhiyun 	case IIO_INTENSITY:
638*4882a593Smuzhiyun 		*val = rpr0521_samp_freq_i[reg].als_hz;
639*4882a593Smuzhiyun 		*val2 = rpr0521_samp_freq_i[reg].als_uhz;
640*4882a593Smuzhiyun 		return 0;
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	case IIO_PROXIMITY:
643*4882a593Smuzhiyun 		*val = rpr0521_samp_freq_i[reg].pxs_hz;
644*4882a593Smuzhiyun 		*val2 = rpr0521_samp_freq_i[reg].pxs_uhz;
645*4882a593Smuzhiyun 		return 0;
646*4882a593Smuzhiyun 
647*4882a593Smuzhiyun 	default:
648*4882a593Smuzhiyun 		return -EINVAL;
649*4882a593Smuzhiyun 	}
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun 
rpr0521_write_samp_freq_common(struct rpr0521_data * data,enum iio_chan_type chan_type,int val,int val2)652*4882a593Smuzhiyun static int rpr0521_write_samp_freq_common(struct rpr0521_data *data,
653*4882a593Smuzhiyun 				enum iio_chan_type chan_type,
654*4882a593Smuzhiyun 				int val, int val2)
655*4882a593Smuzhiyun {
656*4882a593Smuzhiyun 	int i;
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	/*
659*4882a593Smuzhiyun 	 * Ignore channel
660*4882a593Smuzhiyun 	 * both pxs and als are setup only to same freq because of simplicity
661*4882a593Smuzhiyun 	 */
662*4882a593Smuzhiyun 	switch (val) {
663*4882a593Smuzhiyun 	case 0:
664*4882a593Smuzhiyun 		i = 0;
665*4882a593Smuzhiyun 		break;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	case 2:
668*4882a593Smuzhiyun 		if (val2 != 500000)
669*4882a593Smuzhiyun 			return -EINVAL;
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun 		i = 11;
672*4882a593Smuzhiyun 		break;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	case 10:
675*4882a593Smuzhiyun 		i = 6;
676*4882a593Smuzhiyun 		break;
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 	default:
679*4882a593Smuzhiyun 		return -EINVAL;
680*4882a593Smuzhiyun 	}
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	return regmap_update_bits(data->regmap,
683*4882a593Smuzhiyun 		RPR0521_REG_MODE_CTRL,
684*4882a593Smuzhiyun 		RPR0521_MODE_MEAS_TIME_MASK,
685*4882a593Smuzhiyun 		i);
686*4882a593Smuzhiyun }
687*4882a593Smuzhiyun 
rpr0521_read_ps_offset(struct rpr0521_data * data,int * offset)688*4882a593Smuzhiyun static int rpr0521_read_ps_offset(struct rpr0521_data *data, int *offset)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun 	int ret;
691*4882a593Smuzhiyun 	__le16 buffer;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	ret = regmap_bulk_read(data->regmap,
694*4882a593Smuzhiyun 		RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
695*4882a593Smuzhiyun 
696*4882a593Smuzhiyun 	if (ret < 0) {
697*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Failed to read PS OFFSET register\n");
698*4882a593Smuzhiyun 		return ret;
699*4882a593Smuzhiyun 	}
700*4882a593Smuzhiyun 	*offset = le16_to_cpu(buffer);
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	return ret;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun 
rpr0521_write_ps_offset(struct rpr0521_data * data,int offset)705*4882a593Smuzhiyun static int rpr0521_write_ps_offset(struct rpr0521_data *data, int offset)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun 	int ret;
708*4882a593Smuzhiyun 	__le16 buffer;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	buffer = cpu_to_le16(offset & 0x3ff);
711*4882a593Smuzhiyun 	ret = regmap_raw_write(data->regmap,
712*4882a593Smuzhiyun 		RPR0521_REG_PS_OFFSET_LSB, &buffer, sizeof(buffer));
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	if (ret < 0) {
715*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Failed to write PS OFFSET register\n");
716*4882a593Smuzhiyun 		return ret;
717*4882a593Smuzhiyun 	}
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	return ret;
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun 
rpr0521_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)722*4882a593Smuzhiyun static int rpr0521_read_raw(struct iio_dev *indio_dev,
723*4882a593Smuzhiyun 			    struct iio_chan_spec const *chan, int *val,
724*4882a593Smuzhiyun 			    int *val2, long mask)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
727*4882a593Smuzhiyun 	int ret;
728*4882a593Smuzhiyun 	int busy;
729*4882a593Smuzhiyun 	u8 device_mask;
730*4882a593Smuzhiyun 	__le16 raw_data;
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	switch (mask) {
733*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
734*4882a593Smuzhiyun 		if (chan->type != IIO_INTENSITY && chan->type != IIO_PROXIMITY)
735*4882a593Smuzhiyun 			return -EINVAL;
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 		busy = iio_device_claim_direct_mode(indio_dev);
738*4882a593Smuzhiyun 		if (busy)
739*4882a593Smuzhiyun 			return -EBUSY;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 		device_mask = rpr0521_data_reg[chan->address].device_mask;
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 		mutex_lock(&data->lock);
744*4882a593Smuzhiyun 		ret = rpr0521_set_power_state(data, true, device_mask);
745*4882a593Smuzhiyun 		if (ret < 0)
746*4882a593Smuzhiyun 			goto rpr0521_read_raw_out;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 		ret = regmap_bulk_read(data->regmap,
749*4882a593Smuzhiyun 				       rpr0521_data_reg[chan->address].address,
750*4882a593Smuzhiyun 				       &raw_data, sizeof(raw_data));
751*4882a593Smuzhiyun 		if (ret < 0) {
752*4882a593Smuzhiyun 			rpr0521_set_power_state(data, false, device_mask);
753*4882a593Smuzhiyun 			goto rpr0521_read_raw_out;
754*4882a593Smuzhiyun 		}
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 		ret = rpr0521_set_power_state(data, false, device_mask);
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun rpr0521_read_raw_out:
759*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
760*4882a593Smuzhiyun 		iio_device_release_direct_mode(indio_dev);
761*4882a593Smuzhiyun 		if (ret < 0)
762*4882a593Smuzhiyun 			return ret;
763*4882a593Smuzhiyun 
764*4882a593Smuzhiyun 		*val = le16_to_cpu(raw_data);
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 		return IIO_VAL_INT;
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
769*4882a593Smuzhiyun 		mutex_lock(&data->lock);
770*4882a593Smuzhiyun 		ret = rpr0521_get_gain(data, chan->address, val, val2);
771*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
772*4882a593Smuzhiyun 		if (ret < 0)
773*4882a593Smuzhiyun 			return ret;
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SAMP_FREQ:
778*4882a593Smuzhiyun 		mutex_lock(&data->lock);
779*4882a593Smuzhiyun 		ret = rpr0521_read_samp_freq(data, chan->type, val, val2);
780*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
781*4882a593Smuzhiyun 		if (ret < 0)
782*4882a593Smuzhiyun 			return ret;
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	case IIO_CHAN_INFO_OFFSET:
787*4882a593Smuzhiyun 		mutex_lock(&data->lock);
788*4882a593Smuzhiyun 		ret = rpr0521_read_ps_offset(data, val);
789*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
790*4882a593Smuzhiyun 		if (ret < 0)
791*4882a593Smuzhiyun 			return ret;
792*4882a593Smuzhiyun 
793*4882a593Smuzhiyun 		return IIO_VAL_INT;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	default:
796*4882a593Smuzhiyun 		return -EINVAL;
797*4882a593Smuzhiyun 	}
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun 
rpr0521_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)800*4882a593Smuzhiyun static int rpr0521_write_raw(struct iio_dev *indio_dev,
801*4882a593Smuzhiyun 			     struct iio_chan_spec const *chan, int val,
802*4882a593Smuzhiyun 			     int val2, long mask)
803*4882a593Smuzhiyun {
804*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
805*4882a593Smuzhiyun 	int ret;
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	switch (mask) {
808*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
809*4882a593Smuzhiyun 		mutex_lock(&data->lock);
810*4882a593Smuzhiyun 		ret = rpr0521_set_gain(data, chan->address, val, val2);
811*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
812*4882a593Smuzhiyun 
813*4882a593Smuzhiyun 		return ret;
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SAMP_FREQ:
816*4882a593Smuzhiyun 		mutex_lock(&data->lock);
817*4882a593Smuzhiyun 		ret = rpr0521_write_samp_freq_common(data, chan->type,
818*4882a593Smuzhiyun 						     val, val2);
819*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 		return ret;
822*4882a593Smuzhiyun 
823*4882a593Smuzhiyun 	case IIO_CHAN_INFO_OFFSET:
824*4882a593Smuzhiyun 		mutex_lock(&data->lock);
825*4882a593Smuzhiyun 		ret = rpr0521_write_ps_offset(data, val);
826*4882a593Smuzhiyun 		mutex_unlock(&data->lock);
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 		return ret;
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	default:
831*4882a593Smuzhiyun 		return -EINVAL;
832*4882a593Smuzhiyun 	}
833*4882a593Smuzhiyun }
834*4882a593Smuzhiyun 
835*4882a593Smuzhiyun static const struct iio_info rpr0521_info = {
836*4882a593Smuzhiyun 	.read_raw	= rpr0521_read_raw,
837*4882a593Smuzhiyun 	.write_raw	= rpr0521_write_raw,
838*4882a593Smuzhiyun 	.attrs		= &rpr0521_attribute_group,
839*4882a593Smuzhiyun };
840*4882a593Smuzhiyun 
rpr0521_init(struct rpr0521_data * data)841*4882a593Smuzhiyun static int rpr0521_init(struct rpr0521_data *data)
842*4882a593Smuzhiyun {
843*4882a593Smuzhiyun 	int ret;
844*4882a593Smuzhiyun 	int id;
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, RPR0521_REG_ID, &id);
847*4882a593Smuzhiyun 	if (ret < 0) {
848*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Failed to read REG_ID register\n");
849*4882a593Smuzhiyun 		return ret;
850*4882a593Smuzhiyun 	}
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	if (id != RPR0521_MANUFACT_ID) {
853*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Wrong id, got %x, expected %x\n",
854*4882a593Smuzhiyun 			id, RPR0521_MANUFACT_ID);
855*4882a593Smuzhiyun 		return -ENODEV;
856*4882a593Smuzhiyun 	}
857*4882a593Smuzhiyun 
858*4882a593Smuzhiyun 	/* set default measurement time - 100 ms for both ALS and PS */
859*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
860*4882a593Smuzhiyun 				 RPR0521_MODE_MEAS_TIME_MASK,
861*4882a593Smuzhiyun 				 RPR0521_DEFAULT_MEAS_TIME);
862*4882a593Smuzhiyun 	if (ret) {
863*4882a593Smuzhiyun 		pr_err("regmap_update_bits returned %d\n", ret);
864*4882a593Smuzhiyun 		return ret;
865*4882a593Smuzhiyun 	}
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun #ifndef CONFIG_PM
868*4882a593Smuzhiyun 	ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
869*4882a593Smuzhiyun 	if (ret < 0)
870*4882a593Smuzhiyun 		return ret;
871*4882a593Smuzhiyun 	ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
872*4882a593Smuzhiyun 	if (ret < 0)
873*4882a593Smuzhiyun 		return ret;
874*4882a593Smuzhiyun #endif
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	data->irq_timestamp = 0;
877*4882a593Smuzhiyun 
878*4882a593Smuzhiyun 	return 0;
879*4882a593Smuzhiyun }
880*4882a593Smuzhiyun 
rpr0521_poweroff(struct rpr0521_data * data)881*4882a593Smuzhiyun static int rpr0521_poweroff(struct rpr0521_data *data)
882*4882a593Smuzhiyun {
883*4882a593Smuzhiyun 	int ret;
884*4882a593Smuzhiyun 	int tmp;
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	ret = regmap_update_bits(data->regmap, RPR0521_REG_MODE_CTRL,
887*4882a593Smuzhiyun 				 RPR0521_MODE_ALS_MASK |
888*4882a593Smuzhiyun 				 RPR0521_MODE_PXS_MASK,
889*4882a593Smuzhiyun 				 RPR0521_MODE_ALS_DISABLE |
890*4882a593Smuzhiyun 				 RPR0521_MODE_PXS_DISABLE);
891*4882a593Smuzhiyun 	if (ret < 0)
892*4882a593Smuzhiyun 		return ret;
893*4882a593Smuzhiyun 
894*4882a593Smuzhiyun 	data->als_dev_en = false;
895*4882a593Smuzhiyun 	data->pxs_dev_en = false;
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	/*
898*4882a593Smuzhiyun 	 * Int pin keeps state after power off. Set pin to high impedance
899*4882a593Smuzhiyun 	 * mode to prevent power drain.
900*4882a593Smuzhiyun 	 */
901*4882a593Smuzhiyun 	ret = regmap_read(data->regmap, RPR0521_REG_INTERRUPT, &tmp);
902*4882a593Smuzhiyun 	if (ret) {
903*4882a593Smuzhiyun 		dev_err(&data->client->dev, "Failed to reset int pin.\n");
904*4882a593Smuzhiyun 		return ret;
905*4882a593Smuzhiyun 	}
906*4882a593Smuzhiyun 
907*4882a593Smuzhiyun 	return 0;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun 
rpr0521_is_volatile_reg(struct device * dev,unsigned int reg)910*4882a593Smuzhiyun static bool rpr0521_is_volatile_reg(struct device *dev, unsigned int reg)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun 	switch (reg) {
913*4882a593Smuzhiyun 	case RPR0521_REG_MODE_CTRL:
914*4882a593Smuzhiyun 	case RPR0521_REG_ALS_CTRL:
915*4882a593Smuzhiyun 	case RPR0521_REG_PXS_CTRL:
916*4882a593Smuzhiyun 		return false;
917*4882a593Smuzhiyun 	default:
918*4882a593Smuzhiyun 		return true;
919*4882a593Smuzhiyun 	}
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun 
922*4882a593Smuzhiyun static const struct regmap_config rpr0521_regmap_config = {
923*4882a593Smuzhiyun 	.name		= RPR0521_REGMAP_NAME,
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	.reg_bits	= 8,
926*4882a593Smuzhiyun 	.val_bits	= 8,
927*4882a593Smuzhiyun 
928*4882a593Smuzhiyun 	.max_register	= RPR0521_REG_ID,
929*4882a593Smuzhiyun 	.cache_type	= REGCACHE_RBTREE,
930*4882a593Smuzhiyun 	.volatile_reg	= rpr0521_is_volatile_reg,
931*4882a593Smuzhiyun };
932*4882a593Smuzhiyun 
rpr0521_probe(struct i2c_client * client,const struct i2c_device_id * id)933*4882a593Smuzhiyun static int rpr0521_probe(struct i2c_client *client,
934*4882a593Smuzhiyun 			 const struct i2c_device_id *id)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun 	struct rpr0521_data *data;
937*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
938*4882a593Smuzhiyun 	struct regmap *regmap;
939*4882a593Smuzhiyun 	int ret;
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
942*4882a593Smuzhiyun 	if (!indio_dev)
943*4882a593Smuzhiyun 		return -ENOMEM;
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 	regmap = devm_regmap_init_i2c(client, &rpr0521_regmap_config);
946*4882a593Smuzhiyun 	if (IS_ERR(regmap)) {
947*4882a593Smuzhiyun 		dev_err(&client->dev, "regmap_init failed!\n");
948*4882a593Smuzhiyun 		return PTR_ERR(regmap);
949*4882a593Smuzhiyun 	}
950*4882a593Smuzhiyun 
951*4882a593Smuzhiyun 	data = iio_priv(indio_dev);
952*4882a593Smuzhiyun 	i2c_set_clientdata(client, indio_dev);
953*4882a593Smuzhiyun 	data->client = client;
954*4882a593Smuzhiyun 	data->regmap = regmap;
955*4882a593Smuzhiyun 
956*4882a593Smuzhiyun 	mutex_init(&data->lock);
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	indio_dev->info = &rpr0521_info;
959*4882a593Smuzhiyun 	indio_dev->name = RPR0521_DRV_NAME;
960*4882a593Smuzhiyun 	indio_dev->channels = rpr0521_channels;
961*4882a593Smuzhiyun 	indio_dev->num_channels = ARRAY_SIZE(rpr0521_channels);
962*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
963*4882a593Smuzhiyun 
964*4882a593Smuzhiyun 	ret = rpr0521_init(data);
965*4882a593Smuzhiyun 	if (ret < 0) {
966*4882a593Smuzhiyun 		dev_err(&client->dev, "rpr0521 chip init failed\n");
967*4882a593Smuzhiyun 		return ret;
968*4882a593Smuzhiyun 	}
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 	ret = pm_runtime_set_active(&client->dev);
971*4882a593Smuzhiyun 	if (ret < 0)
972*4882a593Smuzhiyun 		goto err_poweroff;
973*4882a593Smuzhiyun 
974*4882a593Smuzhiyun 	pm_runtime_enable(&client->dev);
975*4882a593Smuzhiyun 	pm_runtime_set_autosuspend_delay(&client->dev, RPR0521_SLEEP_DELAY_MS);
976*4882a593Smuzhiyun 	pm_runtime_use_autosuspend(&client->dev);
977*4882a593Smuzhiyun 
978*4882a593Smuzhiyun 	/*
979*4882a593Smuzhiyun 	 * If sensor write/read is needed in _probe after _use_autosuspend,
980*4882a593Smuzhiyun 	 * sensor needs to be _resumed first using rpr0521_set_power_state().
981*4882a593Smuzhiyun 	 */
982*4882a593Smuzhiyun 
983*4882a593Smuzhiyun 	/* IRQ to trigger setup */
984*4882a593Smuzhiyun 	if (client->irq) {
985*4882a593Smuzhiyun 		/* Trigger0 producer setup */
986*4882a593Smuzhiyun 		data->drdy_trigger0 = devm_iio_trigger_alloc(
987*4882a593Smuzhiyun 			indio_dev->dev.parent,
988*4882a593Smuzhiyun 			"%s-dev%d", indio_dev->name, indio_dev->id);
989*4882a593Smuzhiyun 		if (!data->drdy_trigger0) {
990*4882a593Smuzhiyun 			ret = -ENOMEM;
991*4882a593Smuzhiyun 			goto err_pm_disable;
992*4882a593Smuzhiyun 		}
993*4882a593Smuzhiyun 		data->drdy_trigger0->dev.parent = indio_dev->dev.parent;
994*4882a593Smuzhiyun 		data->drdy_trigger0->ops = &rpr0521_trigger_ops;
995*4882a593Smuzhiyun 		indio_dev->available_scan_masks = rpr0521_available_scan_masks;
996*4882a593Smuzhiyun 		iio_trigger_set_drvdata(data->drdy_trigger0, indio_dev);
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 		/* Ties irq to trigger producer handler. */
999*4882a593Smuzhiyun 		ret = devm_request_threaded_irq(&client->dev, client->irq,
1000*4882a593Smuzhiyun 			rpr0521_drdy_irq_handler, rpr0521_drdy_irq_thread,
1001*4882a593Smuzhiyun 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
1002*4882a593Smuzhiyun 			RPR0521_IRQ_NAME, indio_dev);
1003*4882a593Smuzhiyun 		if (ret < 0) {
1004*4882a593Smuzhiyun 			dev_err(&client->dev, "request irq %d for trigger0 failed\n",
1005*4882a593Smuzhiyun 				client->irq);
1006*4882a593Smuzhiyun 			goto err_pm_disable;
1007*4882a593Smuzhiyun 			}
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun 		ret = devm_iio_trigger_register(indio_dev->dev.parent,
1010*4882a593Smuzhiyun 						data->drdy_trigger0);
1011*4882a593Smuzhiyun 		if (ret) {
1012*4882a593Smuzhiyun 			dev_err(&client->dev, "iio trigger register failed\n");
1013*4882a593Smuzhiyun 			goto err_pm_disable;
1014*4882a593Smuzhiyun 		}
1015*4882a593Smuzhiyun 
1016*4882a593Smuzhiyun 		/*
1017*4882a593Smuzhiyun 		 * Now whole pipe from physical interrupt (irq defined by
1018*4882a593Smuzhiyun 		 * devicetree to device) to trigger0 output is set up.
1019*4882a593Smuzhiyun 		 */
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 		/* Trigger consumer setup */
1022*4882a593Smuzhiyun 		ret = devm_iio_triggered_buffer_setup(indio_dev->dev.parent,
1023*4882a593Smuzhiyun 			indio_dev,
1024*4882a593Smuzhiyun 			rpr0521_trigger_consumer_store_time,
1025*4882a593Smuzhiyun 			rpr0521_trigger_consumer_handler,
1026*4882a593Smuzhiyun 			&rpr0521_buffer_setup_ops);
1027*4882a593Smuzhiyun 		if (ret < 0) {
1028*4882a593Smuzhiyun 			dev_err(&client->dev, "iio triggered buffer setup failed\n");
1029*4882a593Smuzhiyun 			goto err_pm_disable;
1030*4882a593Smuzhiyun 		}
1031*4882a593Smuzhiyun 	}
1032*4882a593Smuzhiyun 
1033*4882a593Smuzhiyun 	ret = iio_device_register(indio_dev);
1034*4882a593Smuzhiyun 	if (ret)
1035*4882a593Smuzhiyun 		goto err_pm_disable;
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	return 0;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun err_pm_disable:
1040*4882a593Smuzhiyun 	pm_runtime_disable(&client->dev);
1041*4882a593Smuzhiyun 	pm_runtime_set_suspended(&client->dev);
1042*4882a593Smuzhiyun 	pm_runtime_put_noidle(&client->dev);
1043*4882a593Smuzhiyun err_poweroff:
1044*4882a593Smuzhiyun 	rpr0521_poweroff(data);
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	return ret;
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun 
rpr0521_remove(struct i2c_client * client)1049*4882a593Smuzhiyun static int rpr0521_remove(struct i2c_client *client)
1050*4882a593Smuzhiyun {
1051*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
1052*4882a593Smuzhiyun 
1053*4882a593Smuzhiyun 	iio_device_unregister(indio_dev);
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun 	pm_runtime_disable(&client->dev);
1056*4882a593Smuzhiyun 	pm_runtime_set_suspended(&client->dev);
1057*4882a593Smuzhiyun 	pm_runtime_put_noidle(&client->dev);
1058*4882a593Smuzhiyun 
1059*4882a593Smuzhiyun 	rpr0521_poweroff(iio_priv(indio_dev));
1060*4882a593Smuzhiyun 
1061*4882a593Smuzhiyun 	return 0;
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun 
1064*4882a593Smuzhiyun #ifdef CONFIG_PM
rpr0521_runtime_suspend(struct device * dev)1065*4882a593Smuzhiyun static int rpr0521_runtime_suspend(struct device *dev)
1066*4882a593Smuzhiyun {
1067*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1068*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
1069*4882a593Smuzhiyun 	int ret;
1070*4882a593Smuzhiyun 
1071*4882a593Smuzhiyun 	mutex_lock(&data->lock);
1072*4882a593Smuzhiyun 	/* If measurements are enabled, enable them on resume */
1073*4882a593Smuzhiyun 	if (!data->als_need_dis)
1074*4882a593Smuzhiyun 		data->als_ps_need_en = data->als_dev_en;
1075*4882a593Smuzhiyun 	if (!data->pxs_need_dis)
1076*4882a593Smuzhiyun 		data->pxs_ps_need_en = data->pxs_dev_en;
1077*4882a593Smuzhiyun 
1078*4882a593Smuzhiyun 	/* disable channels and sets {als,pxs}_dev_en to false */
1079*4882a593Smuzhiyun 	ret = rpr0521_poweroff(data);
1080*4882a593Smuzhiyun 	regcache_mark_dirty(data->regmap);
1081*4882a593Smuzhiyun 	mutex_unlock(&data->lock);
1082*4882a593Smuzhiyun 
1083*4882a593Smuzhiyun 	return ret;
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun 
rpr0521_runtime_resume(struct device * dev)1086*4882a593Smuzhiyun static int rpr0521_runtime_resume(struct device *dev)
1087*4882a593Smuzhiyun {
1088*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
1089*4882a593Smuzhiyun 	struct rpr0521_data *data = iio_priv(indio_dev);
1090*4882a593Smuzhiyun 	int ret;
1091*4882a593Smuzhiyun 
1092*4882a593Smuzhiyun 	regcache_sync(data->regmap);
1093*4882a593Smuzhiyun 	if (data->als_ps_need_en) {
1094*4882a593Smuzhiyun 		ret = rpr0521_als_enable(data, RPR0521_MODE_ALS_ENABLE);
1095*4882a593Smuzhiyun 		if (ret < 0)
1096*4882a593Smuzhiyun 			return ret;
1097*4882a593Smuzhiyun 		data->als_ps_need_en = false;
1098*4882a593Smuzhiyun 	}
1099*4882a593Smuzhiyun 
1100*4882a593Smuzhiyun 	if (data->pxs_ps_need_en) {
1101*4882a593Smuzhiyun 		ret = rpr0521_pxs_enable(data, RPR0521_MODE_PXS_ENABLE);
1102*4882a593Smuzhiyun 		if (ret < 0)
1103*4882a593Smuzhiyun 			return ret;
1104*4882a593Smuzhiyun 		data->pxs_ps_need_en = false;
1105*4882a593Smuzhiyun 	}
1106*4882a593Smuzhiyun 	msleep(100);	//wait for first measurement result
1107*4882a593Smuzhiyun 
1108*4882a593Smuzhiyun 	return 0;
1109*4882a593Smuzhiyun }
1110*4882a593Smuzhiyun #endif
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun static const struct dev_pm_ops rpr0521_pm_ops = {
1113*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(rpr0521_runtime_suspend,
1114*4882a593Smuzhiyun 			   rpr0521_runtime_resume, NULL)
1115*4882a593Smuzhiyun };
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun static const struct acpi_device_id rpr0521_acpi_match[] = {
1118*4882a593Smuzhiyun 	{"RPR0521", 0},
1119*4882a593Smuzhiyun 	{ }
1120*4882a593Smuzhiyun };
1121*4882a593Smuzhiyun MODULE_DEVICE_TABLE(acpi, rpr0521_acpi_match);
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun static const struct i2c_device_id rpr0521_id[] = {
1124*4882a593Smuzhiyun 	{"rpr0521", 0},
1125*4882a593Smuzhiyun 	{ }
1126*4882a593Smuzhiyun };
1127*4882a593Smuzhiyun 
1128*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, rpr0521_id);
1129*4882a593Smuzhiyun 
1130*4882a593Smuzhiyun static struct i2c_driver rpr0521_driver = {
1131*4882a593Smuzhiyun 	.driver = {
1132*4882a593Smuzhiyun 		.name	= RPR0521_DRV_NAME,
1133*4882a593Smuzhiyun 		.pm	= &rpr0521_pm_ops,
1134*4882a593Smuzhiyun 		.acpi_match_table = ACPI_PTR(rpr0521_acpi_match),
1135*4882a593Smuzhiyun 	},
1136*4882a593Smuzhiyun 	.probe		= rpr0521_probe,
1137*4882a593Smuzhiyun 	.remove		= rpr0521_remove,
1138*4882a593Smuzhiyun 	.id_table	= rpr0521_id,
1139*4882a593Smuzhiyun };
1140*4882a593Smuzhiyun 
1141*4882a593Smuzhiyun module_i2c_driver(rpr0521_driver);
1142*4882a593Smuzhiyun 
1143*4882a593Smuzhiyun MODULE_AUTHOR("Daniel Baluta <daniel.baluta@intel.com>");
1144*4882a593Smuzhiyun MODULE_DESCRIPTION("RPR0521 ROHM Ambient Light and Proximity Sensor driver");
1145*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
1146