1/*
2 * Copyright (c) 2015 Intel Corporation
3 *
4 * Driver for TXC PA12203001 Proximity and Ambient Light Sensor.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 * To do: Interrupt support.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/acpi.h>
15#include <linux/delay.h>
16#include <linux/i2c.h>
17#include <linux/iio/iio.h>
18#include <linux/iio/sysfs.h>
19#include <linux/mutex.h>
20#include <linux/pm.h>
21#include <linux/pm_runtime.h>
22#include <linux/regmap.h>
23
24#define PA12203001_DRIVER_NAME	"pa12203001"
25
26#define PA12203001_REG_CFG0		0x00
27#define PA12203001_REG_CFG1		0x01
28#define PA12203001_REG_CFG2		0x02
29#define PA12203001_REG_CFG3		0x03
30
31#define PA12203001_REG_ADL		0x0b
32#define PA12203001_REG_PDH		0x0e
33
34#define PA12203001_REG_POFS		0x10
35#define PA12203001_REG_PSET		0x11
36
37#define PA12203001_ALS_EN_MASK		BIT(0)
38#define PA12203001_PX_EN_MASK		BIT(1)
39#define PA12203001_PX_NORMAL_MODE_MASK		GENMASK(7, 6)
40#define PA12203001_AFSR_MASK		GENMASK(5, 4)
41#define PA12203001_AFSR_SHIFT		4
42
43#define PA12203001_PSCAN			0x03
44
45/* als range 31000, ps, als disabled */
46#define PA12203001_REG_CFG0_DEFAULT		0x30
47
48/* led current: 100 mA */
49#define PA12203001_REG_CFG1_DEFAULT		0x20
50
51/* ps mode: normal, interrupts not active */
52#define PA12203001_REG_CFG2_DEFAULT		0xcc
53
54#define PA12203001_REG_CFG3_DEFAULT		0x00
55
56#define PA12203001_SLEEP_DELAY_MS		3000
57
58#define PA12203001_CHIP_ENABLE		0xff
59#define PA12203001_CHIP_DISABLE		0x00
60
61/* available scales: corresponding to [500, 4000, 7000, 31000]  lux */
62static const int pa12203001_scales[] = { 7629, 61036, 106813, 473029};
63
64struct pa12203001_data {
65	struct i2c_client *client;
66
67	/* protect device states */
68	struct mutex lock;
69
70	bool als_enabled;
71	bool px_enabled;
72	bool als_needs_enable;
73	bool px_needs_enable;
74
75	struct regmap *map;
76};
77
78static const struct {
79	u8 reg;
80	u8 val;
81} regvals[] = {
82	{PA12203001_REG_CFG0, PA12203001_REG_CFG0_DEFAULT},
83	{PA12203001_REG_CFG1, PA12203001_REG_CFG1_DEFAULT},
84	{PA12203001_REG_CFG2, PA12203001_REG_CFG2_DEFAULT},
85	{PA12203001_REG_CFG3, PA12203001_REG_CFG3_DEFAULT},
86	{PA12203001_REG_PSET, PA12203001_PSCAN},
87};
88
89static IIO_CONST_ATTR(in_illuminance_scale_available,
90		      "0.007629 0.061036 0.106813 0.473029");
91
92static struct attribute *pa12203001_attrs[] = {
93	&iio_const_attr_in_illuminance_scale_available.dev_attr.attr,
94	NULL
95};
96
97static const struct attribute_group pa12203001_attr_group = {
98	.attrs = pa12203001_attrs,
99};
100
101static const struct iio_chan_spec pa12203001_channels[] = {
102	{
103		.type = IIO_LIGHT,
104		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
105				      BIT(IIO_CHAN_INFO_SCALE),
106	},
107	{
108		.type = IIO_PROXIMITY,
109		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
110	}
111};
112
113static const struct regmap_range pa12203001_volatile_regs_ranges[] = {
114	regmap_reg_range(PA12203001_REG_ADL, PA12203001_REG_ADL + 1),
115	regmap_reg_range(PA12203001_REG_PDH, PA12203001_REG_PDH),
116};
117
118static const struct regmap_access_table pa12203001_volatile_regs = {
119	.yes_ranges = pa12203001_volatile_regs_ranges,
120	.n_yes_ranges = ARRAY_SIZE(pa12203001_volatile_regs_ranges),
121};
122
123static const struct regmap_config pa12203001_regmap_config = {
124	.reg_bits = 8,
125	.val_bits = 8,
126	.max_register = PA12203001_REG_PSET,
127	.cache_type = REGCACHE_RBTREE,
128	.volatile_table = &pa12203001_volatile_regs,
129};
130
131static inline int pa12203001_als_enable(struct pa12203001_data *data, u8 enable)
132{
133	int ret;
134
135	ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
136				 PA12203001_ALS_EN_MASK, enable);
137	if (ret < 0)
138		return ret;
139
140	data->als_enabled = !!enable;
141
142	return 0;
143}
144
145static inline int pa12203001_px_enable(struct pa12203001_data *data, u8 enable)
146{
147	int ret;
148
149	ret = regmap_update_bits(data->map, PA12203001_REG_CFG0,
150				 PA12203001_PX_EN_MASK, enable);
151	if (ret < 0)
152		return ret;
153
154	data->px_enabled = !!enable;
155
156	return 0;
157}
158
159static int pa12203001_set_power_state(struct pa12203001_data *data, bool on,
160				      u8 mask)
161{
162#ifdef CONFIG_PM
163	int ret;
164
165	if (on && (mask & PA12203001_ALS_EN_MASK)) {
166		mutex_lock(&data->lock);
167		if (data->px_enabled) {
168			ret = pa12203001_als_enable(data,
169						    PA12203001_ALS_EN_MASK);
170			if (ret < 0)
171				goto err;
172		} else {
173			data->als_needs_enable = true;
174		}
175		mutex_unlock(&data->lock);
176	}
177
178	if (on && (mask & PA12203001_PX_EN_MASK)) {
179		mutex_lock(&data->lock);
180		if (data->als_enabled) {
181			ret = pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
182			if (ret < 0)
183				goto err;
184		} else {
185			data->px_needs_enable = true;
186		}
187		mutex_unlock(&data->lock);
188	}
189
190	if (on) {
191		ret = pm_runtime_get_sync(&data->client->dev);
192		if (ret < 0)
193			pm_runtime_put_noidle(&data->client->dev);
194
195	} else {
196		pm_runtime_mark_last_busy(&data->client->dev);
197		ret = pm_runtime_put_autosuspend(&data->client->dev);
198	}
199
200	return ret;
201
202err:
203	mutex_unlock(&data->lock);
204	return ret;
205
206#endif
207	return 0;
208}
209
210static int pa12203001_read_raw(struct iio_dev *indio_dev,
211			       struct iio_chan_spec const *chan, int *val,
212			       int *val2, long mask)
213{
214	struct pa12203001_data *data = iio_priv(indio_dev);
215	int ret;
216	u8 dev_mask;
217	unsigned int reg_byte;
218	__le16 reg_word;
219
220	switch (mask) {
221	case IIO_CHAN_INFO_RAW:
222		switch (chan->type) {
223		case IIO_LIGHT:
224			dev_mask = PA12203001_ALS_EN_MASK;
225			ret = pa12203001_set_power_state(data, true, dev_mask);
226			if (ret < 0)
227				return ret;
228			/*
229			 * ALS ADC value is stored in registers
230			 * PA12203001_REG_ADL and in PA12203001_REG_ADL + 1.
231			 */
232			ret = regmap_bulk_read(data->map, PA12203001_REG_ADL,
233					       &reg_word, 2);
234			if (ret < 0)
235				goto reg_err;
236
237			*val = le16_to_cpu(reg_word);
238			ret = pa12203001_set_power_state(data, false, dev_mask);
239			if (ret < 0)
240				return ret;
241			break;
242		case IIO_PROXIMITY:
243			dev_mask = PA12203001_PX_EN_MASK;
244			ret = pa12203001_set_power_state(data, true, dev_mask);
245			if (ret < 0)
246				return ret;
247			ret = regmap_read(data->map, PA12203001_REG_PDH,
248					  &reg_byte);
249			if (ret < 0)
250				goto reg_err;
251
252			*val = reg_byte;
253			ret = pa12203001_set_power_state(data, false, dev_mask);
254			if (ret < 0)
255				return ret;
256			break;
257		default:
258			return -EINVAL;
259		}
260		return IIO_VAL_INT;
261	case IIO_CHAN_INFO_SCALE:
262		ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
263		if (ret < 0)
264			return ret;
265		*val = 0;
266		reg_byte = (reg_byte & PA12203001_AFSR_MASK);
267		*val2 = pa12203001_scales[reg_byte >> 4];
268		return IIO_VAL_INT_PLUS_MICRO;
269	default:
270		return -EINVAL;
271	}
272
273reg_err:
274	pa12203001_set_power_state(data, false, dev_mask);
275	return ret;
276}
277
278static int pa12203001_write_raw(struct iio_dev *indio_dev,
279				struct iio_chan_spec const *chan, int val,
280				int val2, long mask)
281{
282	struct pa12203001_data *data = iio_priv(indio_dev);
283	int i, ret, new_val;
284	unsigned int reg_byte;
285
286	switch (mask) {
287	case IIO_CHAN_INFO_SCALE:
288		ret = regmap_read(data->map, PA12203001_REG_CFG0, &reg_byte);
289		if (val != 0 || ret < 0)
290			return -EINVAL;
291		for (i = 0; i < ARRAY_SIZE(pa12203001_scales); i++) {
292			if (val2 == pa12203001_scales[i]) {
293				new_val = i << PA12203001_AFSR_SHIFT;
294				return regmap_update_bits(data->map,
295							  PA12203001_REG_CFG0,
296							  PA12203001_AFSR_MASK,
297							  new_val);
298			}
299		}
300		break;
301	default:
302		break;
303	}
304
305	return -EINVAL;
306}
307
308static const struct iio_info pa12203001_info = {
309	.driver_module	= THIS_MODULE,
310	.read_raw = pa12203001_read_raw,
311	.write_raw = pa12203001_write_raw,
312	.attrs = &pa12203001_attr_group,
313};
314
315static int pa12203001_init(struct iio_dev *indio_dev)
316{
317	struct pa12203001_data *data = iio_priv(indio_dev);
318	int i, ret;
319
320	for (i = 0; i < ARRAY_SIZE(regvals); i++) {
321		ret = regmap_write(data->map, regvals[i].reg, regvals[i].val);
322		if (ret < 0)
323			return ret;
324	}
325
326	return 0;
327}
328
329static int pa12203001_power_chip(struct iio_dev *indio_dev, u8 state)
330{
331	struct pa12203001_data *data = iio_priv(indio_dev);
332	int ret;
333
334	mutex_lock(&data->lock);
335	ret = pa12203001_als_enable(data, state);
336	if (ret < 0)
337		goto out;
338
339	ret = pa12203001_px_enable(data, state);
340
341out:
342	mutex_unlock(&data->lock);
343	return ret;
344}
345
346static int pa12203001_probe(struct i2c_client *client,
347			    const struct i2c_device_id *id)
348{
349	struct pa12203001_data *data;
350	struct iio_dev *indio_dev;
351	int ret;
352
353	indio_dev = devm_iio_device_alloc(&client->dev,
354					  sizeof(struct pa12203001_data));
355	if (!indio_dev)
356		return -ENOMEM;
357
358	data = iio_priv(indio_dev);
359	i2c_set_clientdata(client, indio_dev);
360	data->client = client;
361
362	data->map = devm_regmap_init_i2c(client, &pa12203001_regmap_config);
363	if (IS_ERR(data->map))
364		return PTR_ERR(data->map);
365
366	mutex_init(&data->lock);
367
368	indio_dev->dev.parent = &client->dev;
369	indio_dev->info = &pa12203001_info;
370	indio_dev->name = PA12203001_DRIVER_NAME;
371	indio_dev->channels = pa12203001_channels;
372	indio_dev->num_channels = ARRAY_SIZE(pa12203001_channels);
373	indio_dev->modes = INDIO_DIRECT_MODE;
374
375	ret = pa12203001_init(indio_dev);
376	if (ret < 0)
377		return ret;
378
379	ret = pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
380	if (ret < 0)
381		return ret;
382
383	ret = pm_runtime_set_active(&client->dev);
384	if (ret < 0) {
385		pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
386		return ret;
387	}
388
389	pm_runtime_enable(&client->dev);
390	pm_runtime_set_autosuspend_delay(&client->dev,
391					 PA12203001_SLEEP_DELAY_MS);
392	pm_runtime_use_autosuspend(&client->dev);
393
394	return iio_device_register(indio_dev);
395}
396
397static int pa12203001_remove(struct i2c_client *client)
398{
399	struct iio_dev *indio_dev = i2c_get_clientdata(client);
400
401	iio_device_unregister(indio_dev);
402
403	pm_runtime_disable(&client->dev);
404	pm_runtime_set_suspended(&client->dev);
405
406	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
407}
408
409#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
410static int pa12203001_suspend(struct device *dev)
411{
412	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
413
414	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_DISABLE);
415}
416#endif
417
418#ifdef CONFIG_PM_SLEEP
419static int pa12203001_resume(struct device *dev)
420{
421	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
422
423	return pa12203001_power_chip(indio_dev, PA12203001_CHIP_ENABLE);
424}
425#endif
426
427#ifdef CONFIG_PM
428static int pa12203001_runtime_resume(struct device *dev)
429{
430	struct pa12203001_data *data;
431
432	data = iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
433
434	mutex_lock(&data->lock);
435	if (data->als_needs_enable) {
436		pa12203001_als_enable(data, PA12203001_ALS_EN_MASK);
437		data->als_needs_enable = false;
438	}
439	if (data->px_needs_enable) {
440		pa12203001_px_enable(data, PA12203001_PX_EN_MASK);
441		data->px_needs_enable = false;
442	}
443	mutex_unlock(&data->lock);
444
445	return 0;
446}
447#endif
448
449static const struct dev_pm_ops pa12203001_pm_ops = {
450	SET_SYSTEM_SLEEP_PM_OPS(pa12203001_suspend, pa12203001_resume)
451	SET_RUNTIME_PM_OPS(pa12203001_suspend, pa12203001_runtime_resume, NULL)
452};
453
454static const struct acpi_device_id pa12203001_acpi_match[] = {
455	{ "TXCPA122", 0},
456	{}
457};
458
459MODULE_DEVICE_TABLE(acpi, pa12203001_acpi_match);
460
461static const struct i2c_device_id pa12203001_id[] = {
462		{"txcpa122", 0},
463		{}
464};
465
466MODULE_DEVICE_TABLE(i2c, pa12203001_id);
467
468static struct i2c_driver pa12203001_driver = {
469	.driver = {
470		.name = PA12203001_DRIVER_NAME,
471		.pm = &pa12203001_pm_ops,
472		.acpi_match_table = ACPI_PTR(pa12203001_acpi_match),
473	},
474	.probe = pa12203001_probe,
475	.remove = pa12203001_remove,
476	.id_table = pa12203001_id,
477
478};
479module_i2c_driver(pa12203001_driver);
480
481MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
482MODULE_DESCRIPTION("Driver for TXC PA12203001 Proximity and Light Sensor");
483MODULE_LICENSE("GPL v2");
484