cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

isl29028.c (16938B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * IIO driver for the light sensor ISL29028.
      4 * ISL29028 is Concurrent Ambient Light and Proximity Sensor
      5 *
      6 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
      7 * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
      8 *
      9 * Datasheets:
     10 *  - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
     11 *  - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
     12 */
     13
     14#include <linux/module.h>
     15#include <linux/i2c.h>
     16#include <linux/err.h>
     17#include <linux/mutex.h>
     18#include <linux/delay.h>
     19#include <linux/slab.h>
     20#include <linux/regmap.h>
     21#include <linux/iio/iio.h>
     22#include <linux/iio/sysfs.h>
     23#include <linux/pm_runtime.h>
     24
     25#define ISL29028_CONV_TIME_MS			100
     26
     27#define ISL29028_REG_CONFIGURE			0x01
     28
     29#define ISL29028_CONF_ALS_IR_MODE_ALS		0
     30#define ISL29028_CONF_ALS_IR_MODE_IR		BIT(0)
     31#define ISL29028_CONF_ALS_IR_MODE_MASK		BIT(0)
     32
     33#define ISL29028_CONF_ALS_RANGE_LOW_LUX		0
     34#define ISL29028_CONF_ALS_RANGE_HIGH_LUX	BIT(1)
     35#define ISL29028_CONF_ALS_RANGE_MASK		BIT(1)
     36
     37#define ISL29028_CONF_ALS_DIS			0
     38#define ISL29028_CONF_ALS_EN			BIT(2)
     39#define ISL29028_CONF_ALS_EN_MASK		BIT(2)
     40
     41#define ISL29028_CONF_PROX_SLP_SH		4
     42#define ISL29028_CONF_PROX_SLP_MASK		(7 << ISL29028_CONF_PROX_SLP_SH)
     43
     44#define ISL29028_CONF_PROX_EN			BIT(7)
     45#define ISL29028_CONF_PROX_EN_MASK		BIT(7)
     46
     47#define ISL29028_REG_INTERRUPT			0x02
     48
     49#define ISL29028_REG_PROX_DATA			0x08
     50#define ISL29028_REG_ALSIR_L			0x09
     51#define ISL29028_REG_ALSIR_U			0x0A
     52
     53#define ISL29028_REG_TEST1_MODE			0x0E
     54#define ISL29028_REG_TEST2_MODE			0x0F
     55
     56#define ISL29028_NUM_REGS			(ISL29028_REG_TEST2_MODE + 1)
     57
     58#define ISL29028_POWER_OFF_DELAY_MS		2000
     59
     60struct isl29028_prox_data {
     61	int sampling_int;
     62	int sampling_fract;
     63	int sleep_time;
     64};
     65
     66static const struct isl29028_prox_data isl29028_prox_data[] = {
     67	{   1, 250000, 800 },
     68	{   2, 500000, 400 },
     69	{   5,      0, 200 },
     70	{  10,      0, 100 },
     71	{  13, 300000,  75 },
     72	{  20,      0,  50 },
     73	{  80,      0,  13 }, /*
     74			       * Note: Data sheet lists 12.5 ms sleep time.
     75			       * Round up a half millisecond for msleep().
     76			       */
     77	{ 100,  0,   0 }
     78};
     79
     80enum isl29028_als_ir_mode {
     81	ISL29028_MODE_NONE = 0,
     82	ISL29028_MODE_ALS,
     83	ISL29028_MODE_IR,
     84};
     85
     86struct isl29028_chip {
     87	struct mutex			lock;
     88	struct regmap			*regmap;
     89	int				prox_sampling_int;
     90	int				prox_sampling_frac;
     91	bool				enable_prox;
     92	int				lux_scale;
     93	enum isl29028_als_ir_mode	als_ir_mode;
     94};
     95
     96static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
     97{
     98	int i;
     99
    100	for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
    101		if (isl29028_prox_data[i].sampling_int == sampling_int &&
    102		    isl29028_prox_data[i].sampling_fract == sampling_fract)
    103			return i;
    104	}
    105
    106	return -EINVAL;
    107}
    108
    109static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
    110					int sampling_int, int sampling_fract)
    111{
    112	struct device *dev = regmap_get_device(chip->regmap);
    113	int sleep_index, ret;
    114
    115	sleep_index = isl29028_find_prox_sleep_index(sampling_int,
    116						     sampling_fract);
    117	if (sleep_index < 0)
    118		return sleep_index;
    119
    120	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    121				 ISL29028_CONF_PROX_SLP_MASK,
    122				 sleep_index << ISL29028_CONF_PROX_SLP_SH);
    123
    124	if (ret < 0) {
    125		dev_err(dev, "%s(): Error %d setting the proximity sampling\n",
    126			__func__, ret);
    127		return ret;
    128	}
    129
    130	chip->prox_sampling_int = sampling_int;
    131	chip->prox_sampling_frac = sampling_fract;
    132
    133	return ret;
    134}
    135
    136static int isl29028_enable_proximity(struct isl29028_chip *chip)
    137{
    138	int prox_index, ret;
    139
    140	ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
    141					   chip->prox_sampling_frac);
    142	if (ret < 0)
    143		return ret;
    144
    145	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    146				 ISL29028_CONF_PROX_EN_MASK,
    147				 ISL29028_CONF_PROX_EN);
    148	if (ret < 0)
    149		return ret;
    150
    151	/* Wait for conversion to be complete for first sample */
    152	prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
    153						    chip->prox_sampling_frac);
    154	if (prox_index < 0)
    155		return prox_index;
    156
    157	msleep(isl29028_prox_data[prox_index].sleep_time);
    158
    159	return 0;
    160}
    161
    162static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
    163{
    164	struct device *dev = regmap_get_device(chip->regmap);
    165	int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX :
    166					ISL29028_CONF_ALS_RANGE_LOW_LUX;
    167	int ret;
    168
    169	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    170				 ISL29028_CONF_ALS_RANGE_MASK, val);
    171	if (ret < 0) {
    172		dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__,
    173			ret);
    174		return ret;
    175	}
    176
    177	chip->lux_scale = lux_scale;
    178
    179	return ret;
    180}
    181
    182static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
    183				    enum isl29028_als_ir_mode mode)
    184{
    185	int ret;
    186
    187	if (chip->als_ir_mode == mode)
    188		return 0;
    189
    190	ret = isl29028_set_als_scale(chip, chip->lux_scale);
    191	if (ret < 0)
    192		return ret;
    193
    194	switch (mode) {
    195	case ISL29028_MODE_ALS:
    196		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    197					 ISL29028_CONF_ALS_IR_MODE_MASK,
    198					 ISL29028_CONF_ALS_IR_MODE_ALS);
    199		if (ret < 0)
    200			return ret;
    201
    202		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    203					 ISL29028_CONF_ALS_RANGE_MASK,
    204					 ISL29028_CONF_ALS_RANGE_HIGH_LUX);
    205		break;
    206	case ISL29028_MODE_IR:
    207		ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    208					 ISL29028_CONF_ALS_IR_MODE_MASK,
    209					 ISL29028_CONF_ALS_IR_MODE_IR);
    210		break;
    211	case ISL29028_MODE_NONE:
    212		return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    213					  ISL29028_CONF_ALS_EN_MASK,
    214					  ISL29028_CONF_ALS_DIS);
    215	}
    216
    217	if (ret < 0)
    218		return ret;
    219
    220	/* Enable the ALS/IR */
    221	ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
    222				 ISL29028_CONF_ALS_EN_MASK,
    223				 ISL29028_CONF_ALS_EN);
    224	if (ret < 0)
    225		return ret;
    226
    227	/* Need to wait for conversion time if ALS/IR mode enabled */
    228	msleep(ISL29028_CONV_TIME_MS);
    229
    230	chip->als_ir_mode = mode;
    231
    232	return 0;
    233}
    234
    235static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir)
    236{
    237	struct device *dev = regmap_get_device(chip->regmap);
    238	unsigned int lsb;
    239	unsigned int msb;
    240	int ret;
    241
    242	ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb);
    243	if (ret < 0) {
    244		dev_err(dev,
    245			"%s(): Error %d reading register ALSIR_L\n",
    246			__func__, ret);
    247		return ret;
    248	}
    249
    250	ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb);
    251	if (ret < 0) {
    252		dev_err(dev,
    253			"%s(): Error %d reading register ALSIR_U\n",
    254			__func__, ret);
    255		return ret;
    256	}
    257
    258	*als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF);
    259
    260	return 0;
    261}
    262
    263static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
    264{
    265	struct device *dev = regmap_get_device(chip->regmap);
    266	unsigned int data;
    267	int ret;
    268
    269	if (!chip->enable_prox) {
    270		ret = isl29028_enable_proximity(chip);
    271		if (ret < 0)
    272			return ret;
    273
    274		chip->enable_prox = true;
    275	}
    276
    277	ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
    278	if (ret < 0) {
    279		dev_err(dev, "%s(): Error %d reading register PROX_DATA\n",
    280			__func__, ret);
    281		return ret;
    282	}
    283
    284	*prox = data;
    285
    286	return 0;
    287}
    288
    289static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
    290{
    291	struct device *dev = regmap_get_device(chip->regmap);
    292	int ret;
    293	int als_ir_data;
    294
    295	ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
    296	if (ret < 0) {
    297		dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__,
    298			ret);
    299		return ret;
    300	}
    301
    302	ret = isl29028_read_als_ir(chip, &als_ir_data);
    303	if (ret < 0)
    304		return ret;
    305
    306	/*
    307	 * convert als data count to lux.
    308	 * if lux_scale = 125,  lux = count * 0.031
    309	 * if lux_scale = 2000, lux = count * 0.49
    310	 */
    311	if (chip->lux_scale == 125)
    312		als_ir_data = (als_ir_data * 31) / 1000;
    313	else
    314		als_ir_data = (als_ir_data * 49) / 100;
    315
    316	*als_data = als_ir_data;
    317
    318	return 0;
    319}
    320
    321static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
    322{
    323	struct device *dev = regmap_get_device(chip->regmap);
    324	int ret;
    325
    326	ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
    327	if (ret < 0) {
    328		dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__,
    329			ret);
    330		return ret;
    331	}
    332
    333	return isl29028_read_als_ir(chip, ir_data);
    334}
    335
    336static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on)
    337{
    338	struct device *dev = regmap_get_device(chip->regmap);
    339	int ret;
    340
    341	if (on) {
    342		ret = pm_runtime_resume_and_get(dev);
    343	} else {
    344		pm_runtime_mark_last_busy(dev);
    345		ret = pm_runtime_put_autosuspend(dev);
    346	}
    347
    348	return ret;
    349}
    350
    351/* Channel IO */
    352static int isl29028_write_raw(struct iio_dev *indio_dev,
    353			      struct iio_chan_spec const *chan,
    354			      int val, int val2, long mask)
    355{
    356	struct isl29028_chip *chip = iio_priv(indio_dev);
    357	struct device *dev = regmap_get_device(chip->regmap);
    358	int ret;
    359
    360	ret = isl29028_set_pm_runtime_busy(chip, true);
    361	if (ret < 0)
    362		return ret;
    363
    364	mutex_lock(&chip->lock);
    365
    366	ret = -EINVAL;
    367	switch (chan->type) {
    368	case IIO_PROXIMITY:
    369		if (mask != IIO_CHAN_INFO_SAMP_FREQ) {
    370			dev_err(dev,
    371				"%s(): proximity: Mask value 0x%08lx is not supported\n",
    372				__func__, mask);
    373			break;
    374		}
    375
    376		if (val < 1 || val > 100) {
    377			dev_err(dev,
    378				"%s(): proximity: Sampling frequency %d is not in the range [1:100]\n",
    379				__func__, val);
    380			break;
    381		}
    382
    383		ret = isl29028_set_proxim_sampling(chip, val, val2);
    384		break;
    385	case IIO_LIGHT:
    386		if (mask != IIO_CHAN_INFO_SCALE) {
    387			dev_err(dev,
    388				"%s(): light: Mask value 0x%08lx is not supported\n",
    389				__func__, mask);
    390			break;
    391		}
    392
    393		if (val != 125 && val != 2000) {
    394			dev_err(dev,
    395				"%s(): light: Lux scale %d is not in the set {125, 2000}\n",
    396				__func__, val);
    397			break;
    398		}
    399
    400		ret = isl29028_set_als_scale(chip, val);
    401		break;
    402	default:
    403		dev_err(dev, "%s(): Unsupported channel type %x\n",
    404			__func__, chan->type);
    405		break;
    406	}
    407
    408	mutex_unlock(&chip->lock);
    409
    410	if (ret < 0)
    411		return ret;
    412
    413	ret = isl29028_set_pm_runtime_busy(chip, false);
    414	if (ret < 0)
    415		return ret;
    416
    417	return ret;
    418}
    419
    420static int isl29028_read_raw(struct iio_dev *indio_dev,
    421			     struct iio_chan_spec const *chan,
    422			     int *val, int *val2, long mask)
    423{
    424	struct isl29028_chip *chip = iio_priv(indio_dev);
    425	struct device *dev = regmap_get_device(chip->regmap);
    426	int ret, pm_ret;
    427
    428	ret = isl29028_set_pm_runtime_busy(chip, true);
    429	if (ret < 0)
    430		return ret;
    431
    432	mutex_lock(&chip->lock);
    433
    434	ret = -EINVAL;
    435	switch (mask) {
    436	case IIO_CHAN_INFO_RAW:
    437	case IIO_CHAN_INFO_PROCESSED:
    438		switch (chan->type) {
    439		case IIO_LIGHT:
    440			ret = isl29028_als_get(chip, val);
    441			break;
    442		case IIO_INTENSITY:
    443			ret = isl29028_ir_get(chip, val);
    444			break;
    445		case IIO_PROXIMITY:
    446			ret = isl29028_read_proxim(chip, val);
    447			break;
    448		default:
    449			break;
    450		}
    451
    452		if (ret < 0)
    453			break;
    454
    455		ret = IIO_VAL_INT;
    456		break;
    457	case IIO_CHAN_INFO_SAMP_FREQ:
    458		if (chan->type != IIO_PROXIMITY)
    459			break;
    460
    461		*val = chip->prox_sampling_int;
    462		*val2 = chip->prox_sampling_frac;
    463		ret = IIO_VAL_INT;
    464		break;
    465	case IIO_CHAN_INFO_SCALE:
    466		if (chan->type != IIO_LIGHT)
    467			break;
    468		*val = chip->lux_scale;
    469		ret = IIO_VAL_INT;
    470		break;
    471	default:
    472		dev_err(dev, "%s(): mask value 0x%08lx is not supported\n",
    473			__func__, mask);
    474		break;
    475	}
    476
    477	mutex_unlock(&chip->lock);
    478
    479	if (ret < 0)
    480		return ret;
    481
    482	/**
    483	 * Preserve the ret variable if the call to
    484	 * isl29028_set_pm_runtime_busy() is successful so the reading
    485	 * (if applicable) is returned to user space.
    486	 */
    487	pm_ret = isl29028_set_pm_runtime_busy(chip, false);
    488	if (pm_ret < 0)
    489		return pm_ret;
    490
    491	return ret;
    492}
    493
    494static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
    495				"1.25 2.5 5 10 13.3 20 80 100");
    496static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
    497
    498#define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
    499static struct attribute *isl29028_attributes[] = {
    500	ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available),
    501	ISL29028_CONST_ATTR(in_illuminance_scale_available),
    502	NULL,
    503};
    504
    505static const struct attribute_group isl29108_group = {
    506	.attrs = isl29028_attributes,
    507};
    508
    509static const struct iio_chan_spec isl29028_channels[] = {
    510	{
    511		.type = IIO_LIGHT,
    512		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
    513		BIT(IIO_CHAN_INFO_SCALE),
    514	}, {
    515		.type = IIO_INTENSITY,
    516		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
    517	}, {
    518		.type = IIO_PROXIMITY,
    519		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    520		BIT(IIO_CHAN_INFO_SAMP_FREQ),
    521	}
    522};
    523
    524static const struct iio_info isl29028_info = {
    525	.attrs = &isl29108_group,
    526	.read_raw = isl29028_read_raw,
    527	.write_raw = isl29028_write_raw,
    528};
    529
    530static int isl29028_clear_configure_reg(struct isl29028_chip *chip)
    531{
    532	struct device *dev = regmap_get_device(chip->regmap);
    533	int ret;
    534
    535	ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0);
    536	if (ret < 0)
    537		dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n",
    538			__func__, ret);
    539
    540	chip->als_ir_mode = ISL29028_MODE_NONE;
    541	chip->enable_prox = false;
    542
    543	return ret;
    544}
    545
    546static bool isl29028_is_volatile_reg(struct device *dev, unsigned int reg)
    547{
    548	switch (reg) {
    549	case ISL29028_REG_INTERRUPT:
    550	case ISL29028_REG_PROX_DATA:
    551	case ISL29028_REG_ALSIR_L:
    552	case ISL29028_REG_ALSIR_U:
    553		return true;
    554	default:
    555		return false;
    556	}
    557}
    558
    559static const struct regmap_config isl29028_regmap_config = {
    560	.reg_bits = 8,
    561	.val_bits = 8,
    562	.volatile_reg = isl29028_is_volatile_reg,
    563	.max_register = ISL29028_NUM_REGS - 1,
    564	.num_reg_defaults_raw = ISL29028_NUM_REGS,
    565	.cache_type = REGCACHE_RBTREE,
    566};
    567
    568static int isl29028_probe(struct i2c_client *client,
    569			  const struct i2c_device_id *id)
    570{
    571	struct isl29028_chip *chip;
    572	struct iio_dev *indio_dev;
    573	int ret;
    574
    575	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
    576	if (!indio_dev)
    577		return -ENOMEM;
    578
    579	chip = iio_priv(indio_dev);
    580
    581	i2c_set_clientdata(client, indio_dev);
    582	mutex_init(&chip->lock);
    583
    584	chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config);
    585	if (IS_ERR(chip->regmap)) {
    586		ret = PTR_ERR(chip->regmap);
    587		dev_err(&client->dev, "%s: Error %d initializing regmap\n",
    588			__func__, ret);
    589		return ret;
    590	}
    591
    592	chip->enable_prox  = false;
    593	chip->prox_sampling_int = 20;
    594	chip->prox_sampling_frac = 0;
    595	chip->lux_scale = 2000;
    596
    597	ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
    598	if (ret < 0) {
    599		dev_err(&client->dev,
    600			"%s(): Error %d writing to TEST1_MODE register\n",
    601			__func__, ret);
    602		return ret;
    603	}
    604
    605	ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
    606	if (ret < 0) {
    607		dev_err(&client->dev,
    608			"%s(): Error %d writing to TEST2_MODE register\n",
    609			__func__, ret);
    610		return ret;
    611	}
    612
    613	ret = isl29028_clear_configure_reg(chip);
    614	if (ret < 0)
    615		return ret;
    616
    617	indio_dev->info = &isl29028_info;
    618	indio_dev->channels = isl29028_channels;
    619	indio_dev->num_channels = ARRAY_SIZE(isl29028_channels);
    620	indio_dev->name = id->name;
    621	indio_dev->modes = INDIO_DIRECT_MODE;
    622
    623	pm_runtime_enable(&client->dev);
    624	pm_runtime_set_autosuspend_delay(&client->dev,
    625					 ISL29028_POWER_OFF_DELAY_MS);
    626	pm_runtime_use_autosuspend(&client->dev);
    627
    628	ret = devm_iio_device_register(indio_dev->dev.parent, indio_dev);
    629	if (ret < 0) {
    630		dev_err(&client->dev,
    631			"%s(): iio registration failed with error %d\n",
    632			__func__, ret);
    633		return ret;
    634	}
    635
    636	return 0;
    637}
    638
    639static int isl29028_remove(struct i2c_client *client)
    640{
    641	struct iio_dev *indio_dev = i2c_get_clientdata(client);
    642	struct isl29028_chip *chip = iio_priv(indio_dev);
    643
    644	iio_device_unregister(indio_dev);
    645
    646	pm_runtime_disable(&client->dev);
    647	pm_runtime_set_suspended(&client->dev);
    648
    649	return isl29028_clear_configure_reg(chip);
    650}
    651
    652static int __maybe_unused isl29028_suspend(struct device *dev)
    653{
    654	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
    655	struct isl29028_chip *chip = iio_priv(indio_dev);
    656	int ret;
    657
    658	mutex_lock(&chip->lock);
    659
    660	ret = isl29028_clear_configure_reg(chip);
    661
    662	mutex_unlock(&chip->lock);
    663
    664	return ret;
    665}
    666
    667static int __maybe_unused isl29028_resume(struct device *dev)
    668{
    669	/**
    670	 * The specific component (ALS/IR or proximity) will enable itself as
    671	 * needed the next time that the user requests a reading. This is done
    672	 * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity().
    673	 */
    674	return 0;
    675}
    676
    677static const struct dev_pm_ops isl29028_pm_ops = {
    678	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
    679				pm_runtime_force_resume)
    680	SET_RUNTIME_PM_OPS(isl29028_suspend, isl29028_resume, NULL)
    681};
    682
    683static const struct i2c_device_id isl29028_id[] = {
    684	{"isl29028", 0},
    685	{"isl29030", 0},
    686	{}
    687};
    688MODULE_DEVICE_TABLE(i2c, isl29028_id);
    689
    690static const struct of_device_id isl29028_of_match[] = {
    691	{ .compatible = "isl,isl29028", }, /* for backward compat., don't use */
    692	{ .compatible = "isil,isl29028", },
    693	{ .compatible = "isil,isl29030", },
    694	{ },
    695};
    696MODULE_DEVICE_TABLE(of, isl29028_of_match);
    697
    698static struct i2c_driver isl29028_driver = {
    699	.driver  = {
    700		.name = "isl29028",
    701		.pm = &isl29028_pm_ops,
    702		.of_match_table = isl29028_of_match,
    703	},
    704	.probe	 = isl29028_probe,
    705	.remove  = isl29028_remove,
    706	.id_table = isl29028_id,
    707};
    708
    709module_i2c_driver(isl29028_driver);
    710
    711MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver");
    712MODULE_LICENSE("GPL v2");
    713MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");