2 * Copyright (c) 2015 Intel Corporation
4 * Driver for TXC PA12203001 Proximity and Ambient Light Sensor.
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.
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>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
24 #define PA12203001_DRIVER_NAME "pa12203001"
26 #define PA12203001_REG_CFG0 0x00
27 #define PA12203001_REG_CFG1 0x01
28 #define PA12203001_REG_CFG2 0x02
29 #define PA12203001_REG_CFG3 0x03
31 #define PA12203001_REG_ADL 0x0b
32 #define PA12203001_REG_PDH 0x0e
34 #define PA12203001_REG_POFS 0x10
35 #define PA12203001_REG_PSET 0x11
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
43 #define PA12203001_PSCAN 0x03
45 /* als range 31000, ps, als disabled */
46 #define PA12203001_REG_CFG0_DEFAULT 0x30
48 /* led current: 100 mA */
49 #define PA12203001_REG_CFG1_DEFAULT 0x20
51 /* ps mode: normal, interrupts not active */
52 #define PA12203001_REG_CFG2_DEFAULT 0xcc
54 #define PA12203001_REG_CFG3_DEFAULT 0x00
56 #define PA12203001_SLEEP_DELAY_MS 3000
58 #define PA12203001_CHIP_ENABLE 0xff
59 #define PA12203001_CHIP_DISABLE 0x00
61 /* available scales: corresponding to [500, 4000, 7000, 31000] lux */
62 static const int pa12203001_scales
[] = { 7629, 61036, 106813, 473029};
64 struct pa12203001_data
{
65 struct i2c_client
*client
;
67 /* protect device states */
72 bool als_needs_enable
;
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
},
89 static IIO_CONST_ATTR(in_illuminance_scale_available
,
90 "0.007629 0.061036 0.106813 0.473029");
92 static struct attribute
*pa12203001_attrs
[] = {
93 &iio_const_attr_in_illuminance_scale_available
.dev_attr
.attr
,
97 static const struct attribute_group pa12203001_attr_group
= {
98 .attrs
= pa12203001_attrs
,
101 static const struct iio_chan_spec pa12203001_channels
[] = {
104 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
105 BIT(IIO_CHAN_INFO_SCALE
),
108 .type
= IIO_PROXIMITY
,
109 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
113 static 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
),
118 static 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
),
123 static const struct regmap_config pa12203001_regmap_config
= {
126 .max_register
= PA12203001_REG_PSET
,
127 .cache_type
= REGCACHE_RBTREE
,
128 .volatile_table
= &pa12203001_volatile_regs
,
131 static inline int pa12203001_als_enable(struct pa12203001_data
*data
, u8 enable
)
135 ret
= regmap_update_bits(data
->map
, PA12203001_REG_CFG0
,
136 PA12203001_ALS_EN_MASK
, enable
);
140 data
->als_enabled
= !!enable
;
145 static inline int pa12203001_px_enable(struct pa12203001_data
*data
, u8 enable
)
149 ret
= regmap_update_bits(data
->map
, PA12203001_REG_CFG0
,
150 PA12203001_PX_EN_MASK
, enable
);
154 data
->px_enabled
= !!enable
;
159 static int pa12203001_set_power_state(struct pa12203001_data
*data
, bool on
,
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
);
173 data
->als_needs_enable
= true;
175 mutex_unlock(&data
->lock
);
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
);
185 data
->px_needs_enable
= true;
187 mutex_unlock(&data
->lock
);
191 ret
= pm_runtime_get_sync(&data
->client
->dev
);
193 pm_runtime_put_noidle(&data
->client
->dev
);
196 pm_runtime_mark_last_busy(&data
->client
->dev
);
197 ret
= pm_runtime_put_autosuspend(&data
->client
->dev
);
203 mutex_unlock(&data
->lock
);
210 static int pa12203001_read_raw(struct iio_dev
*indio_dev
,
211 struct iio_chan_spec
const *chan
, int *val
,
212 int *val2
, long mask
)
214 struct pa12203001_data
*data
= iio_priv(indio_dev
);
217 unsigned int reg_byte
;
221 case IIO_CHAN_INFO_RAW
:
222 switch (chan
->type
) {
224 dev_mask
= PA12203001_ALS_EN_MASK
;
225 ret
= pa12203001_set_power_state(data
, true, dev_mask
);
229 * ALS ADC value is stored in registers
230 * PA12203001_REG_ADL and in PA12203001_REG_ADL + 1.
232 ret
= regmap_bulk_read(data
->map
, PA12203001_REG_ADL
,
237 *val
= le16_to_cpu(reg_word
);
238 ret
= pa12203001_set_power_state(data
, false, dev_mask
);
243 dev_mask
= PA12203001_PX_EN_MASK
;
244 ret
= pa12203001_set_power_state(data
, true, dev_mask
);
247 ret
= regmap_read(data
->map
, PA12203001_REG_PDH
,
253 ret
= pa12203001_set_power_state(data
, false, dev_mask
);
261 case IIO_CHAN_INFO_SCALE
:
262 ret
= regmap_read(data
->map
, PA12203001_REG_CFG0
, ®_byte
);
266 reg_byte
= (reg_byte
& PA12203001_AFSR_MASK
);
267 *val2
= pa12203001_scales
[reg_byte
>> 4];
268 return IIO_VAL_INT_PLUS_MICRO
;
274 pa12203001_set_power_state(data
, false, dev_mask
);
278 static int pa12203001_write_raw(struct iio_dev
*indio_dev
,
279 struct iio_chan_spec
const *chan
, int val
,
282 struct pa12203001_data
*data
= iio_priv(indio_dev
);
284 unsigned int reg_byte
;
287 case IIO_CHAN_INFO_SCALE
:
288 ret
= regmap_read(data
->map
, PA12203001_REG_CFG0
, ®_byte
);
289 if (val
!= 0 || ret
< 0)
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
,
296 PA12203001_AFSR_MASK
,
308 static 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
,
315 static int pa12203001_init(struct iio_dev
*indio_dev
)
317 struct pa12203001_data
*data
= iio_priv(indio_dev
);
320 for (i
= 0; i
< ARRAY_SIZE(regvals
); i
++) {
321 ret
= regmap_write(data
->map
, regvals
[i
].reg
, regvals
[i
].val
);
329 static int pa12203001_power_chip(struct iio_dev
*indio_dev
, u8 state
)
331 struct pa12203001_data
*data
= iio_priv(indio_dev
);
334 mutex_lock(&data
->lock
);
335 ret
= pa12203001_als_enable(data
, state
);
339 ret
= pa12203001_px_enable(data
, state
);
342 mutex_unlock(&data
->lock
);
346 static int pa12203001_probe(struct i2c_client
*client
,
347 const struct i2c_device_id
*id
)
349 struct pa12203001_data
*data
;
350 struct iio_dev
*indio_dev
;
353 indio_dev
= devm_iio_device_alloc(&client
->dev
,
354 sizeof(struct pa12203001_data
));
358 data
= iio_priv(indio_dev
);
359 i2c_set_clientdata(client
, indio_dev
);
360 data
->client
= client
;
362 data
->map
= devm_regmap_init_i2c(client
, &pa12203001_regmap_config
);
363 if (IS_ERR(data
->map
))
364 return PTR_ERR(data
->map
);
366 mutex_init(&data
->lock
);
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
;
375 ret
= pa12203001_init(indio_dev
);
379 ret
= pa12203001_power_chip(indio_dev
, PA12203001_CHIP_ENABLE
);
383 ret
= pm_runtime_set_active(&client
->dev
);
387 pm_runtime_enable(&client
->dev
);
388 pm_runtime_set_autosuspend_delay(&client
->dev
,
389 PA12203001_SLEEP_DELAY_MS
);
390 pm_runtime_use_autosuspend(&client
->dev
);
392 ret
= iio_device_register(indio_dev
);
399 pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
403 static int pa12203001_remove(struct i2c_client
*client
)
405 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
407 iio_device_unregister(indio_dev
);
409 pm_runtime_disable(&client
->dev
);
410 pm_runtime_set_suspended(&client
->dev
);
412 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
415 #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
416 static int pa12203001_suspend(struct device
*dev
)
418 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
420 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
424 #ifdef CONFIG_PM_SLEEP
425 static int pa12203001_resume(struct device
*dev
)
427 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
429 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_ENABLE
);
434 static int pa12203001_runtime_resume(struct device
*dev
)
436 struct pa12203001_data
*data
;
438 data
= iio_priv(i2c_get_clientdata(to_i2c_client(dev
)));
440 mutex_lock(&data
->lock
);
441 if (data
->als_needs_enable
) {
442 pa12203001_als_enable(data
, PA12203001_ALS_EN_MASK
);
443 data
->als_needs_enable
= false;
445 if (data
->px_needs_enable
) {
446 pa12203001_px_enable(data
, PA12203001_PX_EN_MASK
);
447 data
->px_needs_enable
= false;
449 mutex_unlock(&data
->lock
);
455 static const struct dev_pm_ops pa12203001_pm_ops
= {
456 SET_SYSTEM_SLEEP_PM_OPS(pa12203001_suspend
, pa12203001_resume
)
457 SET_RUNTIME_PM_OPS(pa12203001_suspend
, pa12203001_runtime_resume
, NULL
)
460 static const struct acpi_device_id pa12203001_acpi_match
[] = {
465 MODULE_DEVICE_TABLE(acpi
, pa12203001_acpi_match
);
467 static const struct i2c_device_id pa12203001_id
[] = {
472 MODULE_DEVICE_TABLE(i2c
, pa12203001_id
);
474 static struct i2c_driver pa12203001_driver
= {
476 .name
= PA12203001_DRIVER_NAME
,
477 .pm
= &pa12203001_pm_ops
,
478 .acpi_match_table
= ACPI_PTR(pa12203001_acpi_match
),
480 .probe
= pa12203001_probe
,
481 .remove
= pa12203001_remove
,
482 .id_table
= pa12203001_id
,
485 module_i2c_driver(pa12203001_driver
);
487 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
488 MODULE_DESCRIPTION("Driver for TXC PA12203001 Proximity and Light Sensor");
489 MODULE_LICENSE("GPL v2");