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

cm36651.c (19725B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
      4 * Author: Beomho Seo <beomho.seo@samsung.com>
      5 */
      6
      7#include <linux/delay.h>
      8#include <linux/err.h>
      9#include <linux/i2c.h>
     10#include <linux/mutex.h>
     11#include <linux/module.h>
     12#include <linux/interrupt.h>
     13#include <linux/regulator/consumer.h>
     14#include <linux/iio/iio.h>
     15#include <linux/iio/sysfs.h>
     16#include <linux/iio/events.h>
     17
     18/* Slave address 0x19 for PS of 7 bit addressing protocol for I2C */
     19#define CM36651_I2C_ADDR_PS		0x19
     20/* Alert Response Address */
     21#define CM36651_ARA			0x0C
     22
     23/* Ambient light sensor */
     24#define CM36651_CS_CONF1		0x00
     25#define CM36651_CS_CONF2		0x01
     26#define CM36651_ALS_WH_M		0x02
     27#define CM36651_ALS_WH_L		0x03
     28#define CM36651_ALS_WL_M		0x04
     29#define CM36651_ALS_WL_L		0x05
     30#define CM36651_CS_CONF3		0x06
     31#define CM36651_CS_CONF_REG_NUM		0x02
     32
     33/* Proximity sensor */
     34#define CM36651_PS_CONF1		0x00
     35#define CM36651_PS_THD			0x01
     36#define CM36651_PS_CANC			0x02
     37#define CM36651_PS_CONF2		0x03
     38#define CM36651_PS_REG_NUM		0x04
     39
     40/* CS_CONF1 command code */
     41#define CM36651_ALS_ENABLE		0x00
     42#define CM36651_ALS_DISABLE		0x01
     43#define CM36651_ALS_INT_EN		0x02
     44#define CM36651_ALS_THRES		0x04
     45
     46/* CS_CONF2 command code */
     47#define CM36651_CS_CONF2_DEFAULT_BIT	0x08
     48
     49/* CS_CONF3 channel integration time */
     50#define CM36651_CS_IT1			0x00 /* Integration time 80 msec */
     51#define CM36651_CS_IT2			0x40 /* Integration time 160 msec */
     52#define CM36651_CS_IT3			0x80 /* Integration time 320 msec */
     53#define CM36651_CS_IT4			0xC0 /* Integration time 640 msec */
     54
     55/* PS_CONF1 command code */
     56#define CM36651_PS_ENABLE		0x00
     57#define CM36651_PS_DISABLE		0x01
     58#define CM36651_PS_INT_EN		0x02
     59#define CM36651_PS_PERS2		0x04
     60#define CM36651_PS_PERS3		0x08
     61#define CM36651_PS_PERS4		0x0C
     62
     63/* PS_CONF1 command code: integration time */
     64#define CM36651_PS_IT1			0x00 /* Integration time 0.32 msec */
     65#define CM36651_PS_IT2			0x10 /* Integration time 0.42 msec */
     66#define CM36651_PS_IT3			0x20 /* Integration time 0.52 msec */
     67#define CM36651_PS_IT4			0x30 /* Integration time 0.64 msec */
     68
     69/* PS_CONF1 command code: duty ratio */
     70#define CM36651_PS_DR1			0x00 /* Duty ratio 1/80 */
     71#define CM36651_PS_DR2			0x40 /* Duty ratio 1/160 */
     72#define CM36651_PS_DR3			0x80 /* Duty ratio 1/320 */
     73#define CM36651_PS_DR4			0xC0 /* Duty ratio 1/640 */
     74
     75/* PS_THD command code */
     76#define CM36651_PS_INITIAL_THD		0x05
     77
     78/* PS_CANC command code */
     79#define CM36651_PS_CANC_DEFAULT		0x00
     80
     81/* PS_CONF2 command code */
     82#define CM36651_PS_HYS1			0x00
     83#define CM36651_PS_HYS2			0x01
     84#define CM36651_PS_SMART_PERS_EN	0x02
     85#define CM36651_PS_DIR_INT		0x04
     86#define CM36651_PS_MS			0x10
     87
     88#define CM36651_CS_COLOR_NUM		4
     89
     90#define CM36651_CLOSE_PROXIMITY		0x32
     91#define CM36651_FAR_PROXIMITY			0x33
     92
     93#define CM36651_CS_INT_TIME_AVAIL	"0.08 0.16 0.32 0.64"
     94#define CM36651_PS_INT_TIME_AVAIL	"0.000320 0.000420 0.000520 0.000640"
     95
     96enum cm36651_operation_mode {
     97	CM36651_LIGHT_EN,
     98	CM36651_PROXIMITY_EN,
     99	CM36651_PROXIMITY_EV_EN,
    100};
    101
    102enum cm36651_light_channel_idx {
    103	CM36651_LIGHT_CHANNEL_IDX_RED,
    104	CM36651_LIGHT_CHANNEL_IDX_GREEN,
    105	CM36651_LIGHT_CHANNEL_IDX_BLUE,
    106	CM36651_LIGHT_CHANNEL_IDX_CLEAR,
    107};
    108
    109enum cm36651_command {
    110	CM36651_CMD_READ_RAW_LIGHT,
    111	CM36651_CMD_READ_RAW_PROXIMITY,
    112	CM36651_CMD_PROX_EV_EN,
    113	CM36651_CMD_PROX_EV_DIS,
    114};
    115
    116static const u8 cm36651_cs_reg[CM36651_CS_CONF_REG_NUM] = {
    117	CM36651_CS_CONF1,
    118	CM36651_CS_CONF2,
    119};
    120
    121static const u8 cm36651_ps_reg[CM36651_PS_REG_NUM] = {
    122	CM36651_PS_CONF1,
    123	CM36651_PS_THD,
    124	CM36651_PS_CANC,
    125	CM36651_PS_CONF2,
    126};
    127
    128struct cm36651_data {
    129	const struct cm36651_platform_data *pdata;
    130	struct i2c_client *client;
    131	struct i2c_client *ps_client;
    132	struct i2c_client *ara_client;
    133	struct mutex lock;
    134	struct regulator *vled_reg;
    135	unsigned long flags;
    136	int cs_int_time[CM36651_CS_COLOR_NUM];
    137	int ps_int_time;
    138	u8 cs_ctrl_regs[CM36651_CS_CONF_REG_NUM];
    139	u8 ps_ctrl_regs[CM36651_PS_REG_NUM];
    140	u16 color[CM36651_CS_COLOR_NUM];
    141};
    142
    143static int cm36651_setup_reg(struct cm36651_data *cm36651)
    144{
    145	struct i2c_client *client = cm36651->client;
    146	struct i2c_client *ps_client = cm36651->ps_client;
    147	int i, ret;
    148
    149	/* CS initialization */
    150	cm36651->cs_ctrl_regs[CM36651_CS_CONF1] = CM36651_ALS_ENABLE |
    151							     CM36651_ALS_THRES;
    152	cm36651->cs_ctrl_regs[CM36651_CS_CONF2] = CM36651_CS_CONF2_DEFAULT_BIT;
    153
    154	for (i = 0; i < CM36651_CS_CONF_REG_NUM; i++) {
    155		ret = i2c_smbus_write_byte_data(client, cm36651_cs_reg[i],
    156						     cm36651->cs_ctrl_regs[i]);
    157		if (ret < 0)
    158			return ret;
    159	}
    160
    161	/* PS initialization */
    162	cm36651->ps_ctrl_regs[CM36651_PS_CONF1] = CM36651_PS_ENABLE |
    163								CM36651_PS_IT2;
    164	cm36651->ps_ctrl_regs[CM36651_PS_THD] = CM36651_PS_INITIAL_THD;
    165	cm36651->ps_ctrl_regs[CM36651_PS_CANC] = CM36651_PS_CANC_DEFAULT;
    166	cm36651->ps_ctrl_regs[CM36651_PS_CONF2] = CM36651_PS_HYS2 |
    167				CM36651_PS_DIR_INT | CM36651_PS_SMART_PERS_EN;
    168
    169	for (i = 0; i < CM36651_PS_REG_NUM; i++) {
    170		ret = i2c_smbus_write_byte_data(ps_client, cm36651_ps_reg[i],
    171						     cm36651->ps_ctrl_regs[i]);
    172		if (ret < 0)
    173			return ret;
    174	}
    175
    176	/* Set shutdown mode */
    177	ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
    178							  CM36651_ALS_DISABLE);
    179	if (ret < 0)
    180		return ret;
    181
    182	ret = i2c_smbus_write_byte_data(cm36651->ps_client,
    183					 CM36651_PS_CONF1, CM36651_PS_DISABLE);
    184	if (ret < 0)
    185		return ret;
    186
    187	return 0;
    188}
    189
    190static int cm36651_read_output(struct cm36651_data *cm36651,
    191				struct iio_chan_spec const *chan, int *val)
    192{
    193	struct i2c_client *client = cm36651->client;
    194	int ret = -EINVAL;
    195
    196	switch (chan->type) {
    197	case IIO_LIGHT:
    198		*val = i2c_smbus_read_word_data(client, chan->address);
    199		if (*val < 0)
    200			return ret;
    201
    202		ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
    203							CM36651_ALS_DISABLE);
    204		if (ret < 0)
    205			return ret;
    206
    207		ret = IIO_VAL_INT;
    208		break;
    209	case IIO_PROXIMITY:
    210		*val = i2c_smbus_read_byte(cm36651->ps_client);
    211		if (*val < 0)
    212			return ret;
    213
    214		if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
    215			ret = i2c_smbus_write_byte_data(cm36651->ps_client,
    216					CM36651_PS_CONF1, CM36651_PS_DISABLE);
    217			if (ret < 0)
    218				return ret;
    219		}
    220
    221		ret = IIO_VAL_INT;
    222		break;
    223	default:
    224		break;
    225	}
    226
    227	return ret;
    228}
    229
    230static irqreturn_t cm36651_irq_handler(int irq, void *data)
    231{
    232	struct iio_dev *indio_dev = data;
    233	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    234	struct i2c_client *client = cm36651->client;
    235	int ev_dir, ret;
    236	u64 ev_code;
    237
    238	/*
    239	 * The PS INT pin is an active low signal that PS INT move logic low
    240	 * when the object is detect. Once the MCU host received the PS INT
    241	 * "LOW" signal, the Host needs to read the data at Alert Response
    242	 * Address(ARA) to clear the PS INT signal. After clearing the PS
    243	 * INT pin, the PS INT signal toggles from low to high.
    244	 */
    245	ret = i2c_smbus_read_byte(cm36651->ara_client);
    246	if (ret < 0) {
    247		dev_err(&client->dev,
    248				"%s: Data read failed: %d\n", __func__, ret);
    249		return IRQ_HANDLED;
    250	}
    251	switch (ret) {
    252	case CM36651_CLOSE_PROXIMITY:
    253		ev_dir = IIO_EV_DIR_RISING;
    254		break;
    255	case CM36651_FAR_PROXIMITY:
    256		ev_dir = IIO_EV_DIR_FALLING;
    257		break;
    258	default:
    259		dev_err(&client->dev,
    260			"%s: Data read wrong: %d\n", __func__, ret);
    261		return IRQ_HANDLED;
    262	}
    263
    264	ev_code = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY,
    265				CM36651_CMD_READ_RAW_PROXIMITY,
    266				IIO_EV_TYPE_THRESH, ev_dir);
    267
    268	iio_push_event(indio_dev, ev_code, iio_get_time_ns(indio_dev));
    269
    270	return IRQ_HANDLED;
    271}
    272
    273static int cm36651_set_operation_mode(struct cm36651_data *cm36651, int cmd)
    274{
    275	struct i2c_client *client = cm36651->client;
    276	struct i2c_client *ps_client = cm36651->ps_client;
    277	int ret = -EINVAL;
    278
    279	switch (cmd) {
    280	case CM36651_CMD_READ_RAW_LIGHT:
    281		ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF1,
    282				cm36651->cs_ctrl_regs[CM36651_CS_CONF1]);
    283		break;
    284	case CM36651_CMD_READ_RAW_PROXIMITY:
    285		if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags))
    286			return CM36651_PROXIMITY_EV_EN;
    287
    288		ret = i2c_smbus_write_byte_data(ps_client, CM36651_PS_CONF1,
    289				cm36651->ps_ctrl_regs[CM36651_PS_CONF1]);
    290		break;
    291	case CM36651_CMD_PROX_EV_EN:
    292		if (test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
    293			dev_err(&client->dev,
    294				"Already proximity event enable state\n");
    295			return ret;
    296		}
    297		set_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
    298
    299		ret = i2c_smbus_write_byte_data(ps_client,
    300			cm36651_ps_reg[CM36651_PS_CONF1],
    301			CM36651_PS_INT_EN | CM36651_PS_PERS2 | CM36651_PS_IT2);
    302
    303		if (ret < 0) {
    304			dev_err(&client->dev, "Proximity enable event failed\n");
    305			return ret;
    306		}
    307		break;
    308	case CM36651_CMD_PROX_EV_DIS:
    309		if (!test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags)) {
    310			dev_err(&client->dev,
    311				"Already proximity event disable state\n");
    312			return ret;
    313		}
    314		clear_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
    315		ret = i2c_smbus_write_byte_data(ps_client,
    316					CM36651_PS_CONF1, CM36651_PS_DISABLE);
    317		break;
    318	}
    319
    320	if (ret < 0)
    321		dev_err(&client->dev, "Write register failed\n");
    322
    323	return ret;
    324}
    325
    326static int cm36651_read_channel(struct cm36651_data *cm36651,
    327				struct iio_chan_spec const *chan, int *val)
    328{
    329	struct i2c_client *client = cm36651->client;
    330	int cmd, ret;
    331
    332	if (chan->type == IIO_LIGHT)
    333		cmd = CM36651_CMD_READ_RAW_LIGHT;
    334	else if (chan->type == IIO_PROXIMITY)
    335		cmd = CM36651_CMD_READ_RAW_PROXIMITY;
    336	else
    337		return -EINVAL;
    338
    339	ret = cm36651_set_operation_mode(cm36651, cmd);
    340	if (ret < 0) {
    341		dev_err(&client->dev, "CM36651 set operation mode failed\n");
    342		return ret;
    343	}
    344	/* Delay for work after enable operation */
    345	msleep(50);
    346	ret = cm36651_read_output(cm36651, chan, val);
    347	if (ret < 0) {
    348		dev_err(&client->dev, "CM36651 read output failed\n");
    349		return ret;
    350	}
    351
    352	return ret;
    353}
    354
    355static int cm36651_read_int_time(struct cm36651_data *cm36651,
    356				struct iio_chan_spec const *chan, int *val2)
    357{
    358	switch (chan->type) {
    359	case IIO_LIGHT:
    360		if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT1)
    361			*val2 = 80000;
    362		else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT2)
    363			*val2 = 160000;
    364		else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT3)
    365			*val2 = 320000;
    366		else if (cm36651->cs_int_time[chan->address] == CM36651_CS_IT4)
    367			*val2 = 640000;
    368		else
    369			return -EINVAL;
    370		break;
    371	case IIO_PROXIMITY:
    372		if (cm36651->ps_int_time == CM36651_PS_IT1)
    373			*val2 = 320;
    374		else if (cm36651->ps_int_time == CM36651_PS_IT2)
    375			*val2 = 420;
    376		else if (cm36651->ps_int_time == CM36651_PS_IT3)
    377			*val2 = 520;
    378		else if (cm36651->ps_int_time == CM36651_PS_IT4)
    379			*val2 = 640;
    380		else
    381			return -EINVAL;
    382		break;
    383	default:
    384		return -EINVAL;
    385	}
    386
    387	return IIO_VAL_INT_PLUS_MICRO;
    388}
    389
    390static int cm36651_write_int_time(struct cm36651_data *cm36651,
    391				struct iio_chan_spec const *chan, int val)
    392{
    393	struct i2c_client *client = cm36651->client;
    394	struct i2c_client *ps_client = cm36651->ps_client;
    395	int int_time, ret;
    396
    397	switch (chan->type) {
    398	case IIO_LIGHT:
    399		if (val == 80000)
    400			int_time = CM36651_CS_IT1;
    401		else if (val == 160000)
    402			int_time = CM36651_CS_IT2;
    403		else if (val == 320000)
    404			int_time = CM36651_CS_IT3;
    405		else if (val == 640000)
    406			int_time = CM36651_CS_IT4;
    407		else
    408			return -EINVAL;
    409
    410		ret = i2c_smbus_write_byte_data(client, CM36651_CS_CONF3,
    411					   int_time >> 2 * (chan->address));
    412		if (ret < 0) {
    413			dev_err(&client->dev, "CS integration time write failed\n");
    414			return ret;
    415		}
    416		cm36651->cs_int_time[chan->address] = int_time;
    417		break;
    418	case IIO_PROXIMITY:
    419		if (val == 320)
    420			int_time = CM36651_PS_IT1;
    421		else if (val == 420)
    422			int_time = CM36651_PS_IT2;
    423		else if (val == 520)
    424			int_time = CM36651_PS_IT3;
    425		else if (val == 640)
    426			int_time = CM36651_PS_IT4;
    427		else
    428			return -EINVAL;
    429
    430		ret = i2c_smbus_write_byte_data(ps_client,
    431						CM36651_PS_CONF1, int_time);
    432		if (ret < 0) {
    433			dev_err(&client->dev, "PS integration time write failed\n");
    434			return ret;
    435		}
    436		cm36651->ps_int_time = int_time;
    437		break;
    438	default:
    439		return -EINVAL;
    440	}
    441
    442	return ret;
    443}
    444
    445static int cm36651_read_raw(struct iio_dev *indio_dev,
    446			    struct iio_chan_spec const *chan,
    447			    int *val, int *val2, long mask)
    448{
    449	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    450	int ret;
    451
    452	mutex_lock(&cm36651->lock);
    453
    454	switch (mask) {
    455	case IIO_CHAN_INFO_RAW:
    456		ret = cm36651_read_channel(cm36651, chan, val);
    457		break;
    458	case IIO_CHAN_INFO_INT_TIME:
    459		*val = 0;
    460		ret = cm36651_read_int_time(cm36651, chan, val2);
    461		break;
    462	default:
    463		ret = -EINVAL;
    464	}
    465
    466	mutex_unlock(&cm36651->lock);
    467
    468	return ret;
    469}
    470
    471static int cm36651_write_raw(struct iio_dev *indio_dev,
    472			     struct iio_chan_spec const *chan,
    473			     int val, int val2, long mask)
    474{
    475	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    476	struct i2c_client *client = cm36651->client;
    477	int ret = -EINVAL;
    478
    479	if (mask == IIO_CHAN_INFO_INT_TIME) {
    480		ret = cm36651_write_int_time(cm36651, chan, val2);
    481		if (ret < 0)
    482			dev_err(&client->dev, "Integration time write failed\n");
    483	}
    484
    485	return ret;
    486}
    487
    488static int cm36651_read_prox_thresh(struct iio_dev *indio_dev,
    489					const struct iio_chan_spec *chan,
    490					enum iio_event_type type,
    491					enum iio_event_direction dir,
    492					enum iio_event_info info,
    493					int *val, int *val2)
    494{
    495	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    496
    497	*val = cm36651->ps_ctrl_regs[CM36651_PS_THD];
    498
    499	return 0;
    500}
    501
    502static int cm36651_write_prox_thresh(struct iio_dev *indio_dev,
    503					const struct iio_chan_spec *chan,
    504					enum iio_event_type type,
    505					enum iio_event_direction dir,
    506					enum iio_event_info info,
    507					int val, int val2)
    508{
    509	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    510	struct i2c_client *client = cm36651->client;
    511	int ret;
    512
    513	if (val < 3 || val > 255)
    514		return -EINVAL;
    515
    516	cm36651->ps_ctrl_regs[CM36651_PS_THD] = val;
    517	ret = i2c_smbus_write_byte_data(cm36651->ps_client, CM36651_PS_THD,
    518					cm36651->ps_ctrl_regs[CM36651_PS_THD]);
    519
    520	if (ret < 0) {
    521		dev_err(&client->dev, "PS threshold write failed: %d\n", ret);
    522		return ret;
    523	}
    524
    525	return 0;
    526}
    527
    528static int cm36651_write_prox_event_config(struct iio_dev *indio_dev,
    529					const struct iio_chan_spec *chan,
    530					enum iio_event_type type,
    531					enum iio_event_direction dir,
    532					int state)
    533{
    534	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    535	int cmd, ret;
    536
    537	mutex_lock(&cm36651->lock);
    538
    539	cmd = state ? CM36651_CMD_PROX_EV_EN : CM36651_CMD_PROX_EV_DIS;
    540	ret = cm36651_set_operation_mode(cm36651, cmd);
    541
    542	mutex_unlock(&cm36651->lock);
    543
    544	return ret;
    545}
    546
    547static int cm36651_read_prox_event_config(struct iio_dev *indio_dev,
    548					const struct iio_chan_spec *chan,
    549					enum iio_event_type type,
    550					enum iio_event_direction dir)
    551{
    552	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    553	int event_en;
    554
    555	mutex_lock(&cm36651->lock);
    556
    557	event_en = test_bit(CM36651_PROXIMITY_EV_EN, &cm36651->flags);
    558
    559	mutex_unlock(&cm36651->lock);
    560
    561	return event_en;
    562}
    563
    564#define CM36651_LIGHT_CHANNEL(_color, _idx) {		\
    565	.type = IIO_LIGHT,				\
    566	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
    567			BIT(IIO_CHAN_INFO_INT_TIME),	\
    568	.address = _idx,				\
    569	.modified = 1,					\
    570	.channel2 = IIO_MOD_LIGHT_##_color,		\
    571}							\
    572
    573static const struct iio_event_spec cm36651_event_spec[] = {
    574	{
    575		.type = IIO_EV_TYPE_THRESH,
    576		.dir = IIO_EV_DIR_EITHER,
    577		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
    578				BIT(IIO_EV_INFO_ENABLE),
    579	}
    580};
    581
    582static const struct iio_chan_spec cm36651_channels[] = {
    583	{
    584		.type = IIO_PROXIMITY,
    585		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    586				BIT(IIO_CHAN_INFO_INT_TIME),
    587		.event_spec = cm36651_event_spec,
    588		.num_event_specs = ARRAY_SIZE(cm36651_event_spec),
    589	},
    590	CM36651_LIGHT_CHANNEL(RED, CM36651_LIGHT_CHANNEL_IDX_RED),
    591	CM36651_LIGHT_CHANNEL(GREEN, CM36651_LIGHT_CHANNEL_IDX_GREEN),
    592	CM36651_LIGHT_CHANNEL(BLUE, CM36651_LIGHT_CHANNEL_IDX_BLUE),
    593	CM36651_LIGHT_CHANNEL(CLEAR, CM36651_LIGHT_CHANNEL_IDX_CLEAR),
    594};
    595
    596static IIO_CONST_ATTR(in_illuminance_integration_time_available,
    597					CM36651_CS_INT_TIME_AVAIL);
    598static IIO_CONST_ATTR(in_proximity_integration_time_available,
    599					CM36651_PS_INT_TIME_AVAIL);
    600
    601static struct attribute *cm36651_attributes[] = {
    602	&iio_const_attr_in_illuminance_integration_time_available.dev_attr.attr,
    603	&iio_const_attr_in_proximity_integration_time_available.dev_attr.attr,
    604	NULL,
    605};
    606
    607static const struct attribute_group cm36651_attribute_group = {
    608	.attrs = cm36651_attributes
    609};
    610
    611static const struct iio_info cm36651_info = {
    612	.read_raw		= &cm36651_read_raw,
    613	.write_raw		= &cm36651_write_raw,
    614	.read_event_value	= &cm36651_read_prox_thresh,
    615	.write_event_value	= &cm36651_write_prox_thresh,
    616	.read_event_config	= &cm36651_read_prox_event_config,
    617	.write_event_config	= &cm36651_write_prox_event_config,
    618	.attrs			= &cm36651_attribute_group,
    619};
    620
    621static int cm36651_probe(struct i2c_client *client,
    622			     const struct i2c_device_id *id)
    623{
    624	struct cm36651_data *cm36651;
    625	struct iio_dev *indio_dev;
    626	int ret;
    627
    628	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm36651));
    629	if (!indio_dev)
    630		return -ENOMEM;
    631
    632	cm36651 = iio_priv(indio_dev);
    633
    634	cm36651->vled_reg = devm_regulator_get(&client->dev, "vled");
    635	if (IS_ERR(cm36651->vled_reg))
    636		return dev_err_probe(&client->dev, PTR_ERR(cm36651->vled_reg),
    637				     "get regulator vled failed\n");
    638
    639	ret = regulator_enable(cm36651->vled_reg);
    640	if (ret) {
    641		dev_err(&client->dev, "enable regulator vled failed\n");
    642		return ret;
    643	}
    644
    645	i2c_set_clientdata(client, indio_dev);
    646
    647	cm36651->client = client;
    648	cm36651->ps_client = i2c_new_dummy_device(client->adapter,
    649						     CM36651_I2C_ADDR_PS);
    650	if (IS_ERR(cm36651->ps_client)) {
    651		dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
    652		ret = PTR_ERR(cm36651->ps_client);
    653		goto error_disable_reg;
    654	}
    655
    656	cm36651->ara_client = i2c_new_dummy_device(client->adapter, CM36651_ARA);
    657	if (IS_ERR(cm36651->ara_client)) {
    658		dev_err(&client->dev, "%s: new i2c device failed\n", __func__);
    659		ret = PTR_ERR(cm36651->ara_client);
    660		goto error_i2c_unregister_ps;
    661	}
    662
    663	mutex_init(&cm36651->lock);
    664	indio_dev->channels = cm36651_channels;
    665	indio_dev->num_channels = ARRAY_SIZE(cm36651_channels);
    666	indio_dev->info = &cm36651_info;
    667	indio_dev->name = id->name;
    668	indio_dev->modes = INDIO_DIRECT_MODE;
    669
    670	ret = cm36651_setup_reg(cm36651);
    671	if (ret) {
    672		dev_err(&client->dev, "%s: register setup failed\n", __func__);
    673		goto error_i2c_unregister_ara;
    674	}
    675
    676	ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler,
    677					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
    678							"cm36651", indio_dev);
    679	if (ret) {
    680		dev_err(&client->dev, "%s: request irq failed\n", __func__);
    681		goto error_i2c_unregister_ara;
    682	}
    683
    684	ret = iio_device_register(indio_dev);
    685	if (ret) {
    686		dev_err(&client->dev, "%s: regist device failed\n", __func__);
    687		goto error_free_irq;
    688	}
    689
    690	return 0;
    691
    692error_free_irq:
    693	free_irq(client->irq, indio_dev);
    694error_i2c_unregister_ara:
    695	i2c_unregister_device(cm36651->ara_client);
    696error_i2c_unregister_ps:
    697	i2c_unregister_device(cm36651->ps_client);
    698error_disable_reg:
    699	regulator_disable(cm36651->vled_reg);
    700	return ret;
    701}
    702
    703static int cm36651_remove(struct i2c_client *client)
    704{
    705	struct iio_dev *indio_dev = i2c_get_clientdata(client);
    706	struct cm36651_data *cm36651 = iio_priv(indio_dev);
    707
    708	iio_device_unregister(indio_dev);
    709	regulator_disable(cm36651->vled_reg);
    710	free_irq(client->irq, indio_dev);
    711	i2c_unregister_device(cm36651->ps_client);
    712	i2c_unregister_device(cm36651->ara_client);
    713
    714	return 0;
    715}
    716
    717static const struct i2c_device_id cm36651_id[] = {
    718	{ "cm36651", 0 },
    719	{ }
    720};
    721
    722MODULE_DEVICE_TABLE(i2c, cm36651_id);
    723
    724static const struct of_device_id cm36651_of_match[] = {
    725	{ .compatible = "capella,cm36651" },
    726	{ }
    727};
    728MODULE_DEVICE_TABLE(of, cm36651_of_match);
    729
    730static struct i2c_driver cm36651_driver = {
    731	.driver = {
    732		.name	= "cm36651",
    733		.of_match_table = cm36651_of_match,
    734	},
    735	.probe		= cm36651_probe,
    736	.remove		= cm36651_remove,
    737	.id_table	= cm36651_id,
    738};
    739
    740module_i2c_driver(cm36651_driver);
    741
    742MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
    743MODULE_DESCRIPTION("CM36651 proximity/ambient light sensor driver");
    744MODULE_LICENSE("GPL v2");