File Index
Files and directories
Sign in
FILE

gp2ap002.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/light/gp2ap002.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * These are the two Sharp GP2AP002 variants supported by this driver:
  4 * GP2AP002A00F Ambient Light and Proximity Sensor
  5 * GP2AP002S00F Proximity Sensor
  6 *
  7 * Copyright (C) 2020 Linaro Ltd.
  8 * Author: Linus Walleij <linus.walleij@linaro.org>
  9 *
 10 * Based partly on the code in Sony Ericssons GP2AP00200F driver by
 11 * Courtney Cavin and Oskar Andero in drivers/input/misc/gp2ap002a00f.c
 12 * Based partly on a Samsung misc driver submitted by
 13 * Donggeun Kim & Minkyu Kang in 2011:
 14 * https://lore.kernel.org/lkml/1315556546-7445-1-git-send-email-dg77.kim@samsung.com/
 15 * Based partly on a submission by
 16 * Jonathan Bakker and Paweł Chmiel in january 2019:
 17 * https://lore.kernel.org/linux-input/20190125175045.22576-1-pawel.mikolaj.chmiel@gmail.com/
 18 * Based partly on code from the Samsung GT-S7710 by <mjchen@sta.samsung.com>
 19 * Based partly on the code in LG Electronics GP2AP00200F driver by
 20 * Kenobi Lee <sungyoung.lee@lge.com> and EunYoung Cho <ey.cho@lge.com>
 21 */
 22#include <linux/module.h>
 23#include <linux/i2c.h>
 24#include <linux/regmap.h>
 25#include <linux/iio/iio.h>
 26#include <linux/iio/sysfs.h>
 27#include <linux/iio/events.h>
 28#include <linux/iio/consumer.h> /* To get our ADC channel */
 29#include <linux/iio/types.h> /* To deal with our ADC channel */
 30#include <linux/init.h>
 31#include <linux/delay.h>
 32#include <linux/regulator/consumer.h>
 33#include <linux/pm_runtime.h>
 34#include <linux/interrupt.h>
 35#include <linux/bits.h>
 36#include <linux/math64.h>
 37#include <linux/pm.h>
 38
 39#define GP2AP002_PROX_CHANNEL 0
 40#define GP2AP002_ALS_CHANNEL 1
 41
 42/* ------------------------------------------------------------------------ */
 43/* ADDRESS SYMBOL             DATA                                 Init R/W */
 44/*                   D7    D6    D5    D4    D3    D2    D1    D0           */
 45/* ------------------------------------------------------------------------ */
 46/*    0      PROX     X     X     X     X     X     X     X    VO  H'00   R */
 47/*    1      GAIN     X     X     X     X  LED0     X     X     X  H'00   W */
 48/*    2       HYS  HYSD HYSC1 HYSC0     X HYSF3 HYSF2 HYSF1 HYSF0  H'00   W */
 49/*    3     CYCLE     X     X CYCL2 CYCL1 CYCL0  OSC2     X     X  H'00   W */
 50/*    4     OPMOD     X     X     X   ASD     X     X  VCON   SSD  H'00   W */
 51/*    6       CON     X     X     X OCON1 OCON0     X     X     X  H'00   W */
 52/* ------------------------------------------------------------------------ */
 53/* VO   :Proximity sensing result(0: no detection, 1: detection)            */
 54/* LED0 :Select switch for LED driver's On-registence(0:2x higher, 1:normal)*/
 55/* HYSD/HYSF :Adjusts the receiver sensitivity                              */
 56/* OSC  :Select switch internal clocl frequency hoppling(0:effective)       */
 57/* CYCL :Determine the detection cycle(typically 8ms, up to 128x)           */
 58/* SSD  :Software Shutdown function(0:shutdown, 1:operating)                */
 59/* VCON :VOUT output method control(0:normal, 1:interrupt)                  */
 60/* ASD  :Select switch for analog sleep function(0:ineffective, 1:effective)*/
 61/* OCON :Select switch for enabling/disabling VOUT (00:enable, 11:disable)  */
 62
 63#define GP2AP002_PROX				0x00
 64#define GP2AP002_GAIN				0x01
 65#define GP2AP002_HYS				0x02
 66#define GP2AP002_CYCLE				0x03
 67#define GP2AP002_OPMOD				0x04
 68#define GP2AP002_CON				0x06
 69
 70#define GP2AP002_PROX_VO_DETECT			BIT(0)
 71
 72/* Setting this bit to 0 means 2x higher LED resistance */
 73#define GP2AP002_GAIN_LED_NORMAL		BIT(3)
 74
 75/*
 76 * These bits adjusts the proximity sensitivity, determining characteristics
 77 * of the detection distance and its hysteresis.
 78 */
 79#define GP2AP002_HYS_HYSD_SHIFT		7
 80#define GP2AP002_HYS_HYSD_MASK		BIT(7)
 81#define GP2AP002_HYS_HYSC_SHIFT		5
 82#define GP2AP002_HYS_HYSC_MASK		GENMASK(6, 5)
 83#define GP2AP002_HYS_HYSF_SHIFT		0
 84#define GP2AP002_HYS_HYSF_MASK		GENMASK(3, 0)
 85#define GP2AP002_HYS_MASK		(GP2AP002_HYS_HYSD_MASK | \
 86					 GP2AP002_HYS_HYSC_MASK | \
 87					 GP2AP002_HYS_HYSF_MASK)
 88
 89/*
 90 * These values determine the detection cycle response time
 91 * 0: 8ms, 1: 16ms, 2: 32ms, 3: 64ms, 4: 128ms,
 92 * 5: 256ms, 6: 512ms, 7: 1024ms
 93 */
 94#define GP2AP002_CYCLE_CYCL_SHIFT	3
 95#define GP2AP002_CYCLE_CYCL_MASK	GENMASK(5, 3)
 96
 97/*
 98 * Select switch for internal clock frequency hopping
 99 *	0: effective,
100 *	1: ineffective
101 */
102#define GP2AP002_CYCLE_OSC_EFFECTIVE	0
103#define GP2AP002_CYCLE_OSC_INEFFECTIVE	BIT(2)
104#define GP2AP002_CYCLE_OSC_MASK		BIT(2)
105
106/* Analog sleep effective */
107#define GP2AP002_OPMOD_ASD		BIT(4)
108/* Enable chip */
109#define GP2AP002_OPMOD_SSD_OPERATING	BIT(0)
110/* IRQ mode */
111#define GP2AP002_OPMOD_VCON_IRQ		BIT(1)
112#define GP2AP002_OPMOD_MASK		(BIT(0) | BIT(1) | BIT(4))
113
114/*
115 * Select switch for enabling/disabling Vout pin
116 * 0: enable
117 * 2: force to go Low
118 * 3: force to go High
119 */
120#define GP2AP002_CON_OCON_SHIFT		3
121#define GP2AP002_CON_OCON_ENABLE	(0x0 << GP2AP002_CON_OCON_SHIFT)
122#define GP2AP002_CON_OCON_LOW		(0x2 << GP2AP002_CON_OCON_SHIFT)
123#define GP2AP002_CON_OCON_HIGH		(0x3 << GP2AP002_CON_OCON_SHIFT)
124#define GP2AP002_CON_OCON_MASK		(0x3 << GP2AP002_CON_OCON_SHIFT)
125
126/**
127 * struct gp2ap002 - GP2AP002 state
128 * @map: regmap pointer for the i2c regmap
129 * @dev: pointer to parent device
130 * @vdd: regulator controlling VDD
131 * @vio: regulator controlling VIO
132 * @alsout: IIO ADC channel to convert the ALSOUT signal
133 * @hys_far: hysteresis control from device tree
134 * @hys_close: hysteresis control from device tree
135 * @is_gp2ap002s00f: this is the GP2AP002F variant of the chip
136 * @irq: the IRQ line used by this device
137 * @enabled: we cannot read the status of the hardware so we need to
138 * keep track of whether the event is enabled using this state variable
139 */
140struct gp2ap002 {
141	struct regmap *map;
142	struct device *dev;
143	struct regulator *vdd;
144	struct regulator *vio;
145	struct iio_channel *alsout;
146	u8 hys_far;
147	u8 hys_close;
148	bool is_gp2ap002s00f;
149	int irq;
150	bool enabled;
151};
152
153static irqreturn_t gp2ap002_prox_irq(int irq, void *d)
154{
155	struct iio_dev *indio_dev = d;
156	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
157	u64 ev;
158	int val;
159	int ret;
160
161	if (!gp2ap002->enabled)
162		goto err_retrig;
163
164	ret = regmap_read(gp2ap002->map, GP2AP002_PROX, &val);
165	if (ret) {
166		dev_err(gp2ap002->dev, "error reading proximity\n");
167		goto err_retrig;
168	}
169
170	if (val & GP2AP002_PROX_VO_DETECT) {
171		/* Close */
172		dev_dbg(gp2ap002->dev, "close\n");
173		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
174				   gp2ap002->hys_far);
175		if (ret)
176			dev_err(gp2ap002->dev,
177				"error setting up proximity hysteresis\n");
178		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
179					IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING);
180	} else {
181		/* Far */
182		dev_dbg(gp2ap002->dev, "far\n");
183		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
184				   gp2ap002->hys_close);
185		if (ret)
186			dev_err(gp2ap002->dev,
187				"error setting up proximity hysteresis\n");
188		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
189					IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING);
190	}
191	iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
192
193	/*
194	 * After changing hysteresis, we need to wait for one detection
195	 * cycle to see if anything changed, or we will just trigger the
196	 * previous interrupt again. A detection cycle depends on the CYCLE
197	 * register, we are hard-coding ~8 ms in probe() so wait some more
198	 * than this, 20-30 ms.
199	 */
200	usleep_range(20000, 30000);
201
202err_retrig:
203	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
204			   GP2AP002_CON_OCON_ENABLE);
205	if (ret)
206		dev_err(gp2ap002->dev, "error setting up VOUT control\n");
207
208	return IRQ_HANDLED;
209}
210
211/*
212 * This array maps current and lux.
213 *
214 * Ambient light sensing range is 3 to 55000 lux.
215 *
216 * This mapping is based on the following formula.
217 * illuminance = 10 ^ (current[mA] / 10)
218 *
219 * When the ADC measures 0, return 0 lux.
220 */
221static const u16 gp2ap002_illuminance_table[] = {
222	0, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50, 63, 79,
223	100, 126, 158, 200, 251, 316, 398, 501, 631, 794, 1000, 1259, 1585,
224	1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000, 12589, 15849, 19953,
225	25119, 31623, 39811, 50119,
226};
227
228static int gp2ap002_get_lux(struct gp2ap002 *gp2ap002)
229{
230	int ret, res;
231	u16 lux;
232
233	ret = iio_read_channel_processed(gp2ap002->alsout, &res);
234	if (ret < 0)
235		return ret;
236
237	dev_dbg(gp2ap002->dev, "read %d mA from ADC\n", res);
238
239	/* ensure we don't under/overflow */
240	res = clamp(res, 0, (int)ARRAY_SIZE(gp2ap002_illuminance_table) - 1);
241	lux = gp2ap002_illuminance_table[res];
242
243	return (int)lux;
244}
245
246static int gp2ap002_read_raw(struct iio_dev *indio_dev,
247			   struct iio_chan_spec const *chan,
248			   int *val, int *val2, long mask)
249{
250	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
251	int ret;
252
253	pm_runtime_get_sync(gp2ap002->dev);
254
255	switch (mask) {
256	case IIO_CHAN_INFO_RAW:
257		switch (chan->type) {
258		case IIO_LIGHT:
259			ret = gp2ap002_get_lux(gp2ap002);
260			if (ret < 0)
261				return ret;
262			*val = ret;
263			ret = IIO_VAL_INT;
264			goto out;
265		default:
266			ret = -EINVAL;
267			goto out;
268		}
269	default:
270		ret = -EINVAL;
271	}
272
273out:
274	pm_runtime_put_autosuspend(gp2ap002->dev);
275
276	return ret;
277}
278
279static int gp2ap002_init(struct gp2ap002 *gp2ap002)
280{
281	int ret;
282
283	/* Set up the IR LED resistance */
284	ret = regmap_write(gp2ap002->map, GP2AP002_GAIN,
285			   GP2AP002_GAIN_LED_NORMAL);
286	if (ret) {
287		dev_err(gp2ap002->dev, "error setting up LED gain\n");
288		return ret;
289	}
290	ret = regmap_write(gp2ap002->map, GP2AP002_HYS, gp2ap002->hys_far);
291	if (ret) {
292		dev_err(gp2ap002->dev,
293			"error setting up proximity hysteresis\n");
294		return ret;
295	}
296
297	/* Disable internal frequency hopping */
298	ret = regmap_write(gp2ap002->map, GP2AP002_CYCLE,
299			   GP2AP002_CYCLE_OSC_INEFFECTIVE);
300	if (ret) {
301		dev_err(gp2ap002->dev,
302			"error setting up internal frequency hopping\n");
303		return ret;
304	}
305
306	/* Enable chip and IRQ, disable analog sleep */
307	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD,
308			   GP2AP002_OPMOD_SSD_OPERATING |
309			   GP2AP002_OPMOD_VCON_IRQ);
310	if (ret) {
311		dev_err(gp2ap002->dev, "error setting up operation mode\n");
312		return ret;
313	}
314
315	/* Interrupt on VOUT enabled */
316	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
317			   GP2AP002_CON_OCON_ENABLE);
318	if (ret)
319		dev_err(gp2ap002->dev, "error setting up VOUT control\n");
320
321	return ret;
322}
323
324static int gp2ap002_read_event_config(struct iio_dev *indio_dev,
325				      const struct iio_chan_spec *chan,
326				      enum iio_event_type type,
327				      enum iio_event_direction dir)
328{
329	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
330
331	/*
332	 * We just keep track of this internally, as it is not possible to
333	 * query the hardware.
334	 */
335	return gp2ap002->enabled;
336}
337
338static int gp2ap002_write_event_config(struct iio_dev *indio_dev,
339				       const struct iio_chan_spec *chan,
340				       enum iio_event_type type,
341				       enum iio_event_direction dir,
342				       bool state)
343{
344	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
345
346	if (state) {
347		/*
348		 * This will bring the regulators up (unless they are on
349		 * already) and reintialize the sensor by using runtime_pm
350		 * callbacks.
351		 */
352		pm_runtime_get_sync(gp2ap002->dev);
353		gp2ap002->enabled = true;
354	} else {
355		pm_runtime_put_autosuspend(gp2ap002->dev);
356		gp2ap002->enabled = false;
357	}
358
359	return 0;
360}
361
362static const struct iio_info gp2ap002_info = {
363	.read_raw = gp2ap002_read_raw,
364	.read_event_config = gp2ap002_read_event_config,
365	.write_event_config = gp2ap002_write_event_config,
366};
367
368static const struct iio_event_spec gp2ap002_events[] = {
369	{
370		.type = IIO_EV_TYPE_THRESH,
371		.dir = IIO_EV_DIR_EITHER,
372		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
373	},
374};
375
376static const struct iio_chan_spec gp2ap002_channels[] = {
377	{
378		.type = IIO_PROXIMITY,
379		.event_spec = gp2ap002_events,
380		.num_event_specs = ARRAY_SIZE(gp2ap002_events),
381	},
382	{
383		.type = IIO_LIGHT,
384		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
385		.channel = GP2AP002_ALS_CHANNEL,
386	},
387};
388
389/*
390 * We need a special regmap because this hardware expects to
391 * write single bytes to registers but read a 16bit word on some
392 * variants and discard the lower 8 bits so combine
393 * i2c_smbus_read_word_data() with i2c_smbus_write_byte_data()
394 * selectively like this.
395 */
396static int gp2ap002_regmap_i2c_read(void *context, unsigned int reg,
397				    unsigned int *val)
398{
399	struct device *dev = context;
400	struct i2c_client *i2c = to_i2c_client(dev);
401	int ret;
402
403	ret = i2c_smbus_read_word_data(i2c, reg);
404	if (ret < 0)
405		return ret;
406
407	*val = (ret >> 8) & 0xFF;
408
409	return 0;
410}
411
412static int gp2ap002_regmap_i2c_write(void *context, unsigned int reg,
413				     unsigned int val)
414{
415	struct device *dev = context;
416	struct i2c_client *i2c = to_i2c_client(dev);
417
418	return i2c_smbus_write_byte_data(i2c, reg, val);
419}
420
421static const struct regmap_bus gp2ap002_regmap_bus = {
422	.reg_read = gp2ap002_regmap_i2c_read,
423	.reg_write = gp2ap002_regmap_i2c_write,
424};
425
426static int gp2ap002_probe(struct i2c_client *client)
427{
428	struct gp2ap002 *gp2ap002;
429	struct iio_dev *indio_dev;
430	struct device *dev = &client->dev;
431	enum iio_chan_type ch_type;
432	static const struct regmap_config config = {
433		.reg_bits = 8,
434		.val_bits = 8,
435		.max_register = GP2AP002_CON,
436	};
437	struct regmap *regmap;
438	int num_chan;
439	const char *compat;
440	u8 val;
441	int ret;
442
443	indio_dev = devm_iio_device_alloc(dev, sizeof(*gp2ap002));
444	if (!indio_dev)
445		return -ENOMEM;
446	i2c_set_clientdata(client, indio_dev);
447
448	gp2ap002 = iio_priv(indio_dev);
449	gp2ap002->dev = dev;
450
451	/*
452	 * Check the device compatible like this makes it possible to use
453	 * ACPI PRP0001 for registering the sensor using device tree
454	 * properties.
455	 */
456	ret = device_property_read_string(dev, "compatible", &compat);
457	if (ret) {
458		dev_err(dev, "cannot check compatible\n");
459		return ret;
460	}
461	gp2ap002->is_gp2ap002s00f = !strcmp(compat, "sharp,gp2ap002s00f");
462
463	regmap = devm_regmap_init(dev, &gp2ap002_regmap_bus, dev, &config);
464	if (IS_ERR(regmap)) {
465		dev_err(dev, "Failed to register i2c regmap %ld\n", PTR_ERR(regmap));
466		return PTR_ERR(regmap);
467	}
468	gp2ap002->map = regmap;
469
470	/*
471	 * The hysteresis settings are coded into the device tree as values
472	 * to be written into the hysteresis register. The datasheet defines
473	 * modes "A", "B1" and "B2" with fixed values to be use but vendor
474	 * code trees for actual devices are tweaking these values and refer to
475	 * modes named things like "B1.5". To be able to support any devices,
476	 * we allow passing an arbitrary hysteresis setting for "near" and
477	 * "far".
478	 */
479
480	/* Check the device tree for the IR LED hysteresis */
481	ret = device_property_read_u8(dev, "sharp,proximity-far-hysteresis",
482				      &val);
483	if (ret) {
484		dev_err(dev, "failed to obtain proximity far setting\n");
485		return ret;
486	}
487	dev_dbg(dev, "proximity far setting %02x\n", val);
488	gp2ap002->hys_far = val;
489
490	ret = device_property_read_u8(dev, "sharp,proximity-close-hysteresis",
491				      &val);
492	if (ret) {
493		dev_err(dev, "failed to obtain proximity close setting\n");
494		return ret;
495	}
496	dev_dbg(dev, "proximity close setting %02x\n", val);
497	gp2ap002->hys_close = val;
498
499	/* The GP2AP002A00F has a light sensor too */
500	if (!gp2ap002->is_gp2ap002s00f) {
501		gp2ap002->alsout = devm_iio_channel_get(dev, "alsout");
502		if (IS_ERR(gp2ap002->alsout)) {
503			ret = PTR_ERR(gp2ap002->alsout);
504			ret = (ret == -ENODEV) ? -EPROBE_DEFER : ret;
505			return dev_err_probe(dev, ret, "failed to get ALSOUT ADC channel\n");
506		}
507		ret = iio_get_channel_type(gp2ap002->alsout, &ch_type);
508		if (ret < 0)
509			return ret;
510		if (ch_type != IIO_CURRENT) {
511			dev_err(dev,
512				"wrong type of IIO channel specified for ALSOUT\n");
513			return -EINVAL;
514		}
515	}
516
517	gp2ap002->vdd = devm_regulator_get(dev, "vdd");
518	if (IS_ERR(gp2ap002->vdd))
519		return dev_err_probe(dev, PTR_ERR(gp2ap002->vdd),
520				     "failed to get VDD regulator\n");
521
522	gp2ap002->vio = devm_regulator_get(dev, "vio");
523	if (IS_ERR(gp2ap002->vio))
524		return dev_err_probe(dev, PTR_ERR(gp2ap002->vio),
525				     "failed to get VIO regulator\n");
526
527	/* Operating voltage 2.4V .. 3.6V according to datasheet */
528	ret = regulator_set_voltage(gp2ap002->vdd, 2400000, 3600000);
529	if (ret) {
530		dev_err(dev, "failed to sett VDD voltage\n");
531		return ret;
532	}
533
534	/* VIO should be between 1.65V and VDD */
535	ret = regulator_get_voltage(gp2ap002->vdd);
536	if (ret < 0) {
537		dev_err(dev, "failed to get VDD voltage\n");
538		return ret;
539	}
540	ret = regulator_set_voltage(gp2ap002->vio, 1650000, ret);
541	if (ret) {
542		dev_err(dev, "failed to set VIO voltage\n");
543		return ret;
544	}
545
546	ret = regulator_enable(gp2ap002->vdd);
547	if (ret) {
548		dev_err(dev, "failed to enable VDD regulator\n");
549		return ret;
550	}
551	ret = regulator_enable(gp2ap002->vio);
552	if (ret) {
553		dev_err(dev, "failed to enable VIO regulator\n");
554		goto out_disable_vdd;
555	}
556
557	msleep(20);
558
559	/*
560	 * Initialize the device and signal to runtime PM that now we are
561	 * definitely up and using power.
562	 */
563	ret = gp2ap002_init(gp2ap002);
564	if (ret) {
565		dev_err(dev, "initialization failed\n");
566		goto out_disable_vio;
567	}
568	pm_runtime_get_noresume(dev);
569	pm_runtime_set_active(dev);
570	pm_runtime_enable(dev);
571	gp2ap002->enabled = false;
572
573	ret = devm_request_threaded_irq(dev, client->irq, NULL,
574					gp2ap002_prox_irq, IRQF_ONESHOT,
575					"gp2ap002", indio_dev);
576	if (ret) {
577		dev_err(dev, "unable to request IRQ\n");
578		goto out_put_pm;
579	}
580	gp2ap002->irq = client->irq;
581
582	/*
583	 * As the device takes 20 ms + regulator delay to come up with a fresh
584	 * measurement after power-on, do not shut it down unnecessarily.
585	 * Set autosuspend to a one second.
586	 */
587	pm_runtime_set_autosuspend_delay(dev, 1000);
588	pm_runtime_use_autosuspend(dev);
589	pm_runtime_put(dev);
590
591	indio_dev->info = &gp2ap002_info;
592	indio_dev->name = "gp2ap002";
593	indio_dev->channels = gp2ap002_channels;
594	/* Skip light channel for the proximity-only sensor */
595	num_chan = ARRAY_SIZE(gp2ap002_channels);
596	if (gp2ap002->is_gp2ap002s00f)
597		num_chan--;
598	indio_dev->num_channels = num_chan;
599	indio_dev->modes = INDIO_DIRECT_MODE;
600
601	ret = iio_device_register(indio_dev);
602	if (ret)
603		goto out_disable_pm;
604	dev_dbg(dev, "Sharp GP2AP002 probed successfully\n");
605
606	return 0;
607
608out_put_pm:
609	pm_runtime_put_noidle(dev);
610out_disable_pm:
611	pm_runtime_disable(dev);
612out_disable_vio:
613	regulator_disable(gp2ap002->vio);
614out_disable_vdd:
615	regulator_disable(gp2ap002->vdd);
616	return ret;
617}
618
619static void gp2ap002_remove(struct i2c_client *client)
620{
621	struct iio_dev *indio_dev = i2c_get_clientdata(client);
622	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
623	struct device *dev = &client->dev;
624
625	pm_runtime_get_sync(dev);
626	pm_runtime_put_noidle(dev);
627	pm_runtime_disable(dev);
628	iio_device_unregister(indio_dev);
629	regulator_disable(gp2ap002->vio);
630	regulator_disable(gp2ap002->vdd);
631}
632
633static int gp2ap002_runtime_suspend(struct device *dev)
634{
635	struct iio_dev *indio_dev = dev_get_drvdata(dev);
636	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
637	int ret;
638
639	/* Deactivate the IRQ */
640	disable_irq(gp2ap002->irq);
641
642	/* Disable chip and IRQ, everything off */
643	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD, 0x00);
644	if (ret) {
645		dev_err(gp2ap002->dev, "error setting up operation mode\n");
646		return ret;
647	}
648	/*
649	 * As these regulators may be shared, at least we are now in
650	 * sleep even if the regulators aren't really turned off.
651	 */
652	regulator_disable(gp2ap002->vio);
653	regulator_disable(gp2ap002->vdd);
654
655	return 0;
656}
657
658static int gp2ap002_runtime_resume(struct device *dev)
659{
660	struct iio_dev *indio_dev = dev_get_drvdata(dev);
661	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
662	int ret;
663
664	ret = regulator_enable(gp2ap002->vdd);
665	if (ret) {
666		dev_err(dev, "failed to enable VDD regulator in resume path\n");
667		return ret;
668	}
669	ret = regulator_enable(gp2ap002->vio);
670	if (ret) {
671		dev_err(dev, "failed to enable VIO regulator in resume path\n");
672		return ret;
673	}
674
675	msleep(20);
676
677	ret = gp2ap002_init(gp2ap002);
678	if (ret) {
679		dev_err(dev, "re-initialization failed\n");
680		return ret;
681	}
682
683	/* Re-activate the IRQ */
684	enable_irq(gp2ap002->irq);
685
686	return 0;
687}
688
689static DEFINE_RUNTIME_DEV_PM_OPS(gp2ap002_dev_pm_ops, gp2ap002_runtime_suspend,
690				 gp2ap002_runtime_resume, NULL);
691
692static const struct i2c_device_id gp2ap002_id_table[] = {
693	{ "gp2ap002" },
694	{ }
695};
696MODULE_DEVICE_TABLE(i2c, gp2ap002_id_table);
697
698static const struct of_device_id gp2ap002_of_match[] = {
699	{ .compatible = "sharp,gp2ap002a00f" },
700	{ .compatible = "sharp,gp2ap002s00f" },
701	{ }
702};
703MODULE_DEVICE_TABLE(of, gp2ap002_of_match);
704
705static struct i2c_driver gp2ap002_driver = {
706	.driver = {
707		.name = "gp2ap002",
708		.of_match_table = gp2ap002_of_match,
709		.pm = pm_ptr(&gp2ap002_dev_pm_ops),
710	},
711	.probe = gp2ap002_probe,
712	.remove = gp2ap002_remove,
713	.id_table = gp2ap002_id_table,
714};
715module_i2c_driver(gp2ap002_driver);
716
717MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
718MODULE_DESCRIPTION("GP2AP002 ambient light and proximity sensor driver");
719MODULE_LICENSE("GPL v2");
~/ Read-only file preview.