// SPDX-License-Identifier: GPL-2.0-only
/*
 * These are the two Sharp GP2AP002 variants supported by this driver:
 * GP2AP002A00F Ambient Light and Proximity Sensor
 * GP2AP002S00F Proximity Sensor
 *
 * Copyright (C) 2020 Linaro Ltd.
 * Author: Linus Walleij <linus.walleij@linaro.org>
 *
 * Based partly on the code in Sony Ericssons GP2AP00200F driver by
 * Courtney Cavin and Oskar Andero in drivers/input/misc/gp2ap002a00f.c
 * Based partly on a Samsung misc driver submitted by
 * Donggeun Kim & Minkyu Kang in 2011:
 * https://lore.kernel.org/lkml/1315556546-7445-1-git-send-email-dg77.kim@samsung.com/
 * Based partly on a submission by
 * Jonathan Bakker and Paweł Chmiel in january 2019:
 * https://lore.kernel.org/linux-input/20190125175045.22576-1-pawel.mikolaj.chmiel@gmail.com/
 * Based partly on code from the Samsung GT-S7710 by <mjchen@sta.samsung.com>
 * Based partly on the code in LG Electronics GP2AP00200F driver by
 * Kenobi Lee <sungyoung.lee@lge.com> and EunYoung Cho <ey.cho@lge.com>
 */
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/consumer.h> /* To get our ADC channel */
#include <linux/iio/types.h> /* To deal with our ADC channel */
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/interrupt.h>
#include <linux/bits.h>
#include <linux/math64.h>
#include <linux/pm.h>

#define GP2AP002_PROX_CHANNEL 0
#define GP2AP002_ALS_CHANNEL 1

/* ------------------------------------------------------------------------ */
/* ADDRESS SYMBOL             DATA                                 Init R/W */
/*                   D7    D6    D5    D4    D3    D2    D1    D0           */
/* ------------------------------------------------------------------------ */
/*    0      PROX     X     X     X     X     X     X     X    VO  H'00   R */
/*    1      GAIN     X     X     X     X  LED0     X     X     X  H'00   W */
/*    2       HYS  HYSD HYSC1 HYSC0     X HYSF3 HYSF2 HYSF1 HYSF0  H'00   W */
/*    3     CYCLE     X     X CYCL2 CYCL1 CYCL0  OSC2     X     X  H'00   W */
/*    4     OPMOD     X     X     X   ASD     X     X  VCON   SSD  H'00   W */
/*    6       CON     X     X     X OCON1 OCON0     X     X     X  H'00   W */
/* ------------------------------------------------------------------------ */
/* VO   :Proximity sensing result(0: no detection, 1: detection)            */
/* LED0 :Select switch for LED driver's On-registence(0:2x higher, 1:normal)*/
/* HYSD/HYSF :Adjusts the receiver sensitivity                              */
/* OSC  :Select switch internal clocl frequency hoppling(0:effective)       */
/* CYCL :Determine the detection cycle(typically 8ms, up to 128x)           */
/* SSD  :Software Shutdown function(0:shutdown, 1:operating)                */
/* VCON :VOUT output method control(0:normal, 1:interrupt)                  */
/* ASD  :Select switch for analog sleep function(0:ineffective, 1:effective)*/
/* OCON :Select switch for enabling/disabling VOUT (00:enable, 11:disable)  */

#define GP2AP002_PROX				0x00
#define GP2AP002_GAIN				0x01
#define GP2AP002_HYS				0x02
#define GP2AP002_CYCLE				0x03
#define GP2AP002_OPMOD				0x04
#define GP2AP002_CON				0x06

#define GP2AP002_PROX_VO_DETECT			BIT(0)

/* Setting this bit to 0 means 2x higher LED resistance */
#define GP2AP002_GAIN_LED_NORMAL		BIT(3)

/*
 * These bits adjusts the proximity sensitivity, determining characteristics
 * of the detection distance and its hysteresis.
 */
#define GP2AP002_HYS_HYSD_SHIFT		7
#define GP2AP002_HYS_HYSD_MASK		BIT(7)
#define GP2AP002_HYS_HYSC_SHIFT		5
#define GP2AP002_HYS_HYSC_MASK		GENMASK(6, 5)
#define GP2AP002_HYS_HYSF_SHIFT		0
#define GP2AP002_HYS_HYSF_MASK		GENMASK(3, 0)
#define GP2AP002_HYS_MASK		(GP2AP002_HYS_HYSD_MASK | \
					 GP2AP002_HYS_HYSC_MASK | \
					 GP2AP002_HYS_HYSF_MASK)

/*
 * These values determine the detection cycle response time
 * 0: 8ms, 1: 16ms, 2: 32ms, 3: 64ms, 4: 128ms,
 * 5: 256ms, 6: 512ms, 7: 1024ms
 */
#define GP2AP002_CYCLE_CYCL_SHIFT	3
#define GP2AP002_CYCLE_CYCL_MASK	GENMASK(5, 3)

/*
 * Select switch for internal clock frequency hopping
 *	0: effective,
 *	1: ineffective
 */
#define GP2AP002_CYCLE_OSC_EFFECTIVE	0
#define GP2AP002_CYCLE_OSC_INEFFECTIVE	BIT(2)
#define GP2AP002_CYCLE_OSC_MASK		BIT(2)

/* Analog sleep effective */
#define GP2AP002_OPMOD_ASD		BIT(4)
/* Enable chip */
#define GP2AP002_OPMOD_SSD_OPERATING	BIT(0)
/* IRQ mode */
#define GP2AP002_OPMOD_VCON_IRQ		BIT(1)
#define GP2AP002_OPMOD_MASK		(BIT(0) | BIT(1) | BIT(4))

/*
 * Select switch for enabling/disabling Vout pin
 * 0: enable
 * 2: force to go Low
 * 3: force to go High
 */
#define GP2AP002_CON_OCON_SHIFT		3
#define GP2AP002_CON_OCON_ENABLE	(0x0 << GP2AP002_CON_OCON_SHIFT)
#define GP2AP002_CON_OCON_LOW		(0x2 << GP2AP002_CON_OCON_SHIFT)
#define GP2AP002_CON_OCON_HIGH		(0x3 << GP2AP002_CON_OCON_SHIFT)
#define GP2AP002_CON_OCON_MASK		(0x3 << GP2AP002_CON_OCON_SHIFT)

/**
 * struct gp2ap002 - GP2AP002 state
 * @map: regmap pointer for the i2c regmap
 * @dev: pointer to parent device
 * @vdd: regulator controlling VDD
 * @vio: regulator controlling VIO
 * @alsout: IIO ADC channel to convert the ALSOUT signal
 * @hys_far: hysteresis control from device tree
 * @hys_close: hysteresis control from device tree
 * @is_gp2ap002s00f: this is the GP2AP002F variant of the chip
 * @irq: the IRQ line used by this device
 * @enabled: we cannot read the status of the hardware so we need to
 * keep track of whether the event is enabled using this state variable
 */
struct gp2ap002 {
	struct regmap *map;
	struct device *dev;
	struct regulator *vdd;
	struct regulator *vio;
	struct iio_channel *alsout;
	u8 hys_far;
	u8 hys_close;
	bool is_gp2ap002s00f;
	int irq;
	bool enabled;
};

static irqreturn_t gp2ap002_prox_irq(int irq, void *d)
{
	struct iio_dev *indio_dev = d;
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
	u64 ev;
	int val;
	int ret;

	if (!gp2ap002->enabled)
		goto err_retrig;

	ret = regmap_read(gp2ap002->map, GP2AP002_PROX, &val);
	if (ret) {
		dev_err(gp2ap002->dev, "error reading proximity\n");
		goto err_retrig;
	}

	if (val & GP2AP002_PROX_VO_DETECT) {
		/* Close */
		dev_dbg(gp2ap002->dev, "close\n");
		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
				   gp2ap002->hys_far);
		if (ret)
			dev_err(gp2ap002->dev,
				"error setting up proximity hysteresis\n");
		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
					IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING);
	} else {
		/* Far */
		dev_dbg(gp2ap002->dev, "far\n");
		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
				   gp2ap002->hys_close);
		if (ret)
			dev_err(gp2ap002->dev,
				"error setting up proximity hysteresis\n");
		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
					IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING);
	}
	iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));

	/*
	 * After changing hysteresis, we need to wait for one detection
	 * cycle to see if anything changed, or we will just trigger the
	 * previous interrupt again. A detection cycle depends on the CYCLE
	 * register, we are hard-coding ~8 ms in probe() so wait some more
	 * than this, 20-30 ms.
	 */
	usleep_range(20000, 30000);

err_retrig:
	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
			   GP2AP002_CON_OCON_ENABLE);
	if (ret)
		dev_err(gp2ap002->dev, "error setting up VOUT control\n");

	return IRQ_HANDLED;
}

/*
 * This array maps current and lux.
 *
 * Ambient light sensing range is 3 to 55000 lux.
 *
 * This mapping is based on the following formula.
 * illuminance = 10 ^ (current[mA] / 10)
 *
 * When the ADC measures 0, return 0 lux.
 */
static const u16 gp2ap002_illuminance_table[] = {
	0, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50, 63, 79,
	100, 126, 158, 200, 251, 316, 398, 501, 631, 794, 1000, 1259, 1585,
	1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000, 12589, 15849, 19953,
	25119, 31623, 39811, 50119,
};

static int gp2ap002_get_lux(struct gp2ap002 *gp2ap002)
{
	int ret, res;
	u16 lux;

	ret = iio_read_channel_processed(gp2ap002->alsout, &res);
	if (ret < 0)
		return ret;

	dev_dbg(gp2ap002->dev, "read %d mA from ADC\n", res);

	/* ensure we don't under/overflow */
	res = clamp(res, 0, (int)ARRAY_SIZE(gp2ap002_illuminance_table) - 1);
	lux = gp2ap002_illuminance_table[res];

	return (int)lux;
}

static int gp2ap002_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long mask)
{
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
	int ret;

	pm_runtime_get_sync(gp2ap002->dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		switch (chan->type) {
		case IIO_LIGHT:
			ret = gp2ap002_get_lux(gp2ap002);
			if (ret < 0)
				return ret;
			*val = ret;
			ret = IIO_VAL_INT;
			goto out;
		default:
			ret = -EINVAL;
			goto out;
		}
	default:
		ret = -EINVAL;
	}

out:
	pm_runtime_mark_last_busy(gp2ap002->dev);
	pm_runtime_put_autosuspend(gp2ap002->dev);

	return ret;
}

static int gp2ap002_init(struct gp2ap002 *gp2ap002)
{
	int ret;

	/* Set up the IR LED resistance */
	ret = regmap_write(gp2ap002->map, GP2AP002_GAIN,
			   GP2AP002_GAIN_LED_NORMAL);
	if (ret) {
		dev_err(gp2ap002->dev, "error setting up LED gain\n");
		return ret;
	}
	ret = regmap_write(gp2ap002->map, GP2AP002_HYS, gp2ap002->hys_far);
	if (ret) {
		dev_err(gp2ap002->dev,
			"error setting up proximity hysteresis\n");
		return ret;
	}

	/* Disable internal frequency hopping */
	ret = regmap_write(gp2ap002->map, GP2AP002_CYCLE,
			   GP2AP002_CYCLE_OSC_INEFFECTIVE);
	if (ret) {
		dev_err(gp2ap002->dev,
			"error setting up internal frequency hopping\n");
		return ret;
	}

	/* Enable chip and IRQ, disable analog sleep */
	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD,
			   GP2AP002_OPMOD_SSD_OPERATING |
			   GP2AP002_OPMOD_VCON_IRQ);
	if (ret) {
		dev_err(gp2ap002->dev, "error setting up operation mode\n");
		return ret;
	}

	/* Interrupt on VOUT enabled */
	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
			   GP2AP002_CON_OCON_ENABLE);
	if (ret)
		dev_err(gp2ap002->dev, "error setting up VOUT control\n");

	return ret;
}

static int gp2ap002_read_event_config(struct iio_dev *indio_dev,
				      const struct iio_chan_spec *chan,
				      enum iio_event_type type,
				      enum iio_event_direction dir)
{
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);

	/*
	 * We just keep track of this internally, as it is not possible to
	 * query the hardware.
	 */
	return gp2ap002->enabled;
}

static int gp2ap002_write_event_config(struct iio_dev *indio_dev,
				       const struct iio_chan_spec *chan,
				       enum iio_event_type type,
				       enum iio_event_direction dir,
				       int state)
{
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);

	if (state) {
		/*
		 * This will bring the regulators up (unless they are on
		 * already) and reintialize the sensor by using runtime_pm
		 * callbacks.
		 */
		pm_runtime_get_sync(gp2ap002->dev);
		gp2ap002->enabled = true;
	} else {
		pm_runtime_mark_last_busy(gp2ap002->dev);
		pm_runtime_put_autosuspend(gp2ap002->dev);
		gp2ap002->enabled = false;
	}

	return 0;
}

static const struct iio_info gp2ap002_info = {
	.read_raw = gp2ap002_read_raw,
	.read_event_config = gp2ap002_read_event_config,
	.write_event_config = gp2ap002_write_event_config,
};

static const struct iio_event_spec gp2ap002_events[] = {
	{
		.type = IIO_EV_TYPE_THRESH,
		.dir = IIO_EV_DIR_EITHER,
		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
	},
};

static const struct iio_chan_spec gp2ap002_channels[] = {
	{
		.type = IIO_PROXIMITY,
		.event_spec = gp2ap002_events,
		.num_event_specs = ARRAY_SIZE(gp2ap002_events),
	},
	{
		.type = IIO_LIGHT,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.channel = GP2AP002_ALS_CHANNEL,
	},
};

/*
 * We need a special regmap because this hardware expects to
 * write single bytes to registers but read a 16bit word on some
 * variants and discard the lower 8 bits so combine
 * i2c_smbus_read_word_data() with i2c_smbus_write_byte_data()
 * selectively like this.
 */
static int gp2ap002_regmap_i2c_read(void *context, unsigned int reg,
				    unsigned int *val)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);
	int ret;

	ret = i2c_smbus_read_word_data(i2c, reg);
	if (ret < 0)
		return ret;

	*val = (ret >> 8) & 0xFF;

	return 0;
}

static int gp2ap002_regmap_i2c_write(void *context, unsigned int reg,
				     unsigned int val)
{
	struct device *dev = context;
	struct i2c_client *i2c = to_i2c_client(dev);

	return i2c_smbus_write_byte_data(i2c, reg, val);
}

static struct regmap_bus gp2ap002_regmap_bus = {
	.reg_read = gp2ap002_regmap_i2c_read,
	.reg_write = gp2ap002_regmap_i2c_write,
};

static int gp2ap002_probe(struct i2c_client *client)
{
	struct gp2ap002 *gp2ap002;
	struct iio_dev *indio_dev;
	struct device *dev = &client->dev;
	enum iio_chan_type ch_type;
	static const struct regmap_config config = {
		.reg_bits = 8,
		.val_bits = 8,
		.max_register = GP2AP002_CON,
	};
	struct regmap *regmap;
	int num_chan;
	const char *compat;
	u8 val;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*gp2ap002));
	if (!indio_dev)
		return -ENOMEM;
	i2c_set_clientdata(client, indio_dev);

	gp2ap002 = iio_priv(indio_dev);
	gp2ap002->dev = dev;

	/*
	 * Check the device compatible like this makes it possible to use
	 * ACPI PRP0001 for registering the sensor using device tree
	 * properties.
	 */
	ret = device_property_read_string(dev, "compatible", &compat);
	if (ret) {
		dev_err(dev, "cannot check compatible\n");
		return ret;
	}
	gp2ap002->is_gp2ap002s00f = !strcmp(compat, "sharp,gp2ap002s00f");

	regmap = devm_regmap_init(dev, &gp2ap002_regmap_bus, dev, &config);
	if (IS_ERR(regmap)) {
		dev_err(dev, "Failed to register i2c regmap %ld\n", PTR_ERR(regmap));
		return PTR_ERR(regmap);
	}
	gp2ap002->map = regmap;

	/*
	 * The hysteresis settings are coded into the device tree as values
	 * to be written into the hysteresis register. The datasheet defines
	 * modes "A", "B1" and "B2" with fixed values to be use but vendor
	 * code trees for actual devices are tweaking these values and refer to
	 * modes named things like "B1.5". To be able to support any devices,
	 * we allow passing an arbitrary hysteresis setting for "near" and
	 * "far".
	 */

	/* Check the device tree for the IR LED hysteresis */
	ret = device_property_read_u8(dev, "sharp,proximity-far-hysteresis",
				      &val);
	if (ret) {
		dev_err(dev, "failed to obtain proximity far setting\n");
		return ret;
	}
	dev_dbg(dev, "proximity far setting %02x\n", val);
	gp2ap002->hys_far = val;

	ret = device_property_read_u8(dev, "sharp,proximity-close-hysteresis",
				      &val);
	if (ret) {
		dev_err(dev, "failed to obtain proximity close setting\n");
		return ret;
	}
	dev_dbg(dev, "proximity close setting %02x\n", val);
	gp2ap002->hys_close = val;

	/* The GP2AP002A00F has a light sensor too */
	if (!gp2ap002->is_gp2ap002s00f) {
		gp2ap002->alsout = devm_iio_channel_get(dev, "alsout");
		if (IS_ERR(gp2ap002->alsout)) {
			ret = PTR_ERR(gp2ap002->alsout);
			ret = (ret == -ENODEV) ? -EPROBE_DEFER : ret;
			return dev_err_probe(dev, ret, "failed to get ALSOUT ADC channel\n");
		}
		ret = iio_get_channel_type(gp2ap002->alsout, &ch_type);
		if (ret < 0)
			return ret;
		if (ch_type != IIO_CURRENT) {
			dev_err(dev,
				"wrong type of IIO channel specified for ALSOUT\n");
			return -EINVAL;
		}
	}

	gp2ap002->vdd = devm_regulator_get(dev, "vdd");
	if (IS_ERR(gp2ap002->vdd))
		return dev_err_probe(dev, PTR_ERR(gp2ap002->vdd),
				     "failed to get VDD regulator\n");

	gp2ap002->vio = devm_regulator_get(dev, "vio");
	if (IS_ERR(gp2ap002->vio))
		return dev_err_probe(dev, PTR_ERR(gp2ap002->vio),
				     "failed to get VIO regulator\n");

	/* Operating voltage 2.4V .. 3.6V according to datasheet */
	ret = regulator_set_voltage(gp2ap002->vdd, 2400000, 3600000);
	if (ret) {
		dev_err(dev, "failed to sett VDD voltage\n");
		return ret;
	}

	/* VIO should be between 1.65V and VDD */
	ret = regulator_get_voltage(gp2ap002->vdd);
	if (ret < 0) {
		dev_err(dev, "failed to get VDD voltage\n");
		return ret;
	}
	ret = regulator_set_voltage(gp2ap002->vio, 1650000, ret);
	if (ret) {
		dev_err(dev, "failed to set VIO voltage\n");
		return ret;
	}

	ret = regulator_enable(gp2ap002->vdd);
	if (ret) {
		dev_err(dev, "failed to enable VDD regulator\n");
		return ret;
	}
	ret = regulator_enable(gp2ap002->vio);
	if (ret) {
		dev_err(dev, "failed to enable VIO regulator\n");
		goto out_disable_vdd;
	}

	msleep(20);

	/*
	 * Initialize the device and signal to runtime PM that now we are
	 * definitely up and using power.
	 */
	ret = gp2ap002_init(gp2ap002);
	if (ret) {
		dev_err(dev, "initialization failed\n");
		goto out_disable_vio;
	}
	pm_runtime_get_noresume(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);
	gp2ap002->enabled = false;

	ret = devm_request_threaded_irq(dev, client->irq, NULL,
					gp2ap002_prox_irq, IRQF_ONESHOT,
					"gp2ap002", indio_dev);
	if (ret) {
		dev_err(dev, "unable to request IRQ\n");
		goto out_put_pm;
	}
	gp2ap002->irq = client->irq;

	/*
	 * As the device takes 20 ms + regulator delay to come up with a fresh
	 * measurement after power-on, do not shut it down unnecessarily.
	 * Set autosuspend to a one second.
	 */
	pm_runtime_set_autosuspend_delay(dev, 1000);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_put(dev);

	indio_dev->info = &gp2ap002_info;
	indio_dev->name = "gp2ap002";
	indio_dev->channels = gp2ap002_channels;
	/* Skip light channel for the proximity-only sensor */
	num_chan = ARRAY_SIZE(gp2ap002_channels);
	if (gp2ap002->is_gp2ap002s00f)
		num_chan--;
	indio_dev->num_channels = num_chan;
	indio_dev->modes = INDIO_DIRECT_MODE;

	ret = iio_device_register(indio_dev);
	if (ret)
		goto out_disable_pm;
	dev_dbg(dev, "Sharp GP2AP002 probed successfully\n");

	return 0;

out_put_pm:
	pm_runtime_put_noidle(dev);
out_disable_pm:
	pm_runtime_disable(dev);
out_disable_vio:
	regulator_disable(gp2ap002->vio);
out_disable_vdd:
	regulator_disable(gp2ap002->vdd);
	return ret;
}

static void gp2ap002_remove(struct i2c_client *client)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(client);
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
	struct device *dev = &client->dev;

	pm_runtime_get_sync(dev);
	pm_runtime_put_noidle(dev);
	pm_runtime_disable(dev);
	iio_device_unregister(indio_dev);
	regulator_disable(gp2ap002->vio);
	regulator_disable(gp2ap002->vdd);
}

static int gp2ap002_runtime_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
	int ret;

	/* Deactivate the IRQ */
	disable_irq(gp2ap002->irq);

	/* Disable chip and IRQ, everything off */
	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD, 0x00);
	if (ret) {
		dev_err(gp2ap002->dev, "error setting up operation mode\n");
		return ret;
	}
	/*
	 * As these regulators may be shared, at least we are now in
	 * sleep even if the regulators aren't really turned off.
	 */
	regulator_disable(gp2ap002->vio);
	regulator_disable(gp2ap002->vdd);

	return 0;
}

static int gp2ap002_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
	int ret;

	ret = regulator_enable(gp2ap002->vdd);
	if (ret) {
		dev_err(dev, "failed to enable VDD regulator in resume path\n");
		return ret;
	}
	ret = regulator_enable(gp2ap002->vio);
	if (ret) {
		dev_err(dev, "failed to enable VIO regulator in resume path\n");
		return ret;
	}

	msleep(20);

	ret = gp2ap002_init(gp2ap002);
	if (ret) {
		dev_err(dev, "re-initialization failed\n");
		return ret;
	}

	/* Re-activate the IRQ */
	enable_irq(gp2ap002->irq);

	return 0;
}

static DEFINE_RUNTIME_DEV_PM_OPS(gp2ap002_dev_pm_ops, gp2ap002_runtime_suspend,
				 gp2ap002_runtime_resume, NULL);

static const struct i2c_device_id gp2ap002_id_table[] = {
	{ "gp2ap002", 0 },
	{ },
};
MODULE_DEVICE_TABLE(i2c, gp2ap002_id_table);

static const struct of_device_id gp2ap002_of_match[] = {
	{ .compatible = "sharp,gp2ap002a00f" },
	{ .compatible = "sharp,gp2ap002s00f" },
	{ },
};
MODULE_DEVICE_TABLE(of, gp2ap002_of_match);

static struct i2c_driver gp2ap002_driver = {
	.driver = {
		.name = "gp2ap002",
		.of_match_table = gp2ap002_of_match,
		.pm = pm_ptr(&gp2ap002_dev_pm_ops),
	},
	.probe = gp2ap002_probe,
	.remove = gp2ap002_remove,
	.id_table = gp2ap002_id_table,
};
module_i2c_driver(gp2ap002_driver);

MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
MODULE_DESCRIPTION("GP2AP002 ambient light and proximity sensor driver");
MODULE_LICENSE("GPL v2");
