1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015 Intel Corporation
5 * Driver for TXC PA12203001 Proximity and Ambient Light Sensor.
7 * To do: Interrupt support.
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/acpi.h>
13 #include <linux/delay.h>
14 #include <linux/i2c.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/mutex.h>
19 #include <linux/pm_runtime.h>
20 #include <linux/regmap.h>
22 #define PA12203001_DRIVER_NAME "pa12203001"
24 #define PA12203001_REG_CFG0 0x00
25 #define PA12203001_REG_CFG1 0x01
26 #define PA12203001_REG_CFG2 0x02
27 #define PA12203001_REG_CFG3 0x03
29 #define PA12203001_REG_ADL 0x0b
30 #define PA12203001_REG_PDH 0x0e
32 #define PA12203001_REG_POFS 0x10
33 #define PA12203001_REG_PSET 0x11
35 #define PA12203001_ALS_EN_MASK BIT(0)
36 #define PA12203001_PX_EN_MASK BIT(1)
37 #define PA12203001_PX_NORMAL_MODE_MASK GENMASK(7, 6)
38 #define PA12203001_AFSR_MASK GENMASK(5, 4)
39 #define PA12203001_AFSR_SHIFT 4
41 #define PA12203001_PSCAN 0x03
43 /* als range 31000, ps, als disabled */
44 #define PA12203001_REG_CFG0_DEFAULT 0x30
46 /* led current: 100 mA */
47 #define PA12203001_REG_CFG1_DEFAULT 0x20
49 /* ps mode: normal, interrupts not active */
50 #define PA12203001_REG_CFG2_DEFAULT 0xcc
52 #define PA12203001_REG_CFG3_DEFAULT 0x00
54 #define PA12203001_SLEEP_DELAY_MS 3000
56 #define PA12203001_CHIP_ENABLE 0xff
57 #define PA12203001_CHIP_DISABLE 0x00
59 /* available scales: corresponding to [500, 4000, 7000, 31000] lux */
60 static const int pa12203001_scales
[] = { 7629, 61036, 106813, 473029};
62 struct pa12203001_data
{
63 struct i2c_client
*client
;
65 /* protect device states */
70 bool als_needs_enable
;
80 {PA12203001_REG_CFG0
, PA12203001_REG_CFG0_DEFAULT
},
81 {PA12203001_REG_CFG1
, PA12203001_REG_CFG1_DEFAULT
},
82 {PA12203001_REG_CFG2
, PA12203001_REG_CFG2_DEFAULT
},
83 {PA12203001_REG_CFG3
, PA12203001_REG_CFG3_DEFAULT
},
84 {PA12203001_REG_PSET
, PA12203001_PSCAN
},
87 static IIO_CONST_ATTR(in_illuminance_scale_available
,
88 "0.007629 0.061036 0.106813 0.473029");
90 static struct attribute
*pa12203001_attrs
[] = {
91 &iio_const_attr_in_illuminance_scale_available
.dev_attr
.attr
,
95 static const struct attribute_group pa12203001_attr_group
= {
96 .attrs
= pa12203001_attrs
,
99 static const struct iio_chan_spec pa12203001_channels
[] = {
102 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
103 BIT(IIO_CHAN_INFO_SCALE
),
106 .type
= IIO_PROXIMITY
,
107 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
111 static const struct regmap_range pa12203001_volatile_regs_ranges
[] = {
112 regmap_reg_range(PA12203001_REG_ADL
, PA12203001_REG_ADL
+ 1),
113 regmap_reg_range(PA12203001_REG_PDH
, PA12203001_REG_PDH
),
116 static const struct regmap_access_table pa12203001_volatile_regs
= {
117 .yes_ranges
= pa12203001_volatile_regs_ranges
,
118 .n_yes_ranges
= ARRAY_SIZE(pa12203001_volatile_regs_ranges
),
121 static const struct regmap_config pa12203001_regmap_config
= {
124 .max_register
= PA12203001_REG_PSET
,
125 .cache_type
= REGCACHE_RBTREE
,
126 .volatile_table
= &pa12203001_volatile_regs
,
129 static inline int pa12203001_als_enable(struct pa12203001_data
*data
, u8 enable
)
133 ret
= regmap_update_bits(data
->map
, PA12203001_REG_CFG0
,
134 PA12203001_ALS_EN_MASK
, enable
);
138 data
->als_enabled
= !!enable
;
143 static inline int pa12203001_px_enable(struct pa12203001_data
*data
, u8 enable
)
147 ret
= regmap_update_bits(data
->map
, PA12203001_REG_CFG0
,
148 PA12203001_PX_EN_MASK
, enable
);
152 data
->px_enabled
= !!enable
;
157 static int pa12203001_set_power_state(struct pa12203001_data
*data
, bool on
,
163 if (on
&& (mask
& PA12203001_ALS_EN_MASK
)) {
164 mutex_lock(&data
->lock
);
165 if (data
->px_enabled
) {
166 ret
= pa12203001_als_enable(data
,
167 PA12203001_ALS_EN_MASK
);
171 data
->als_needs_enable
= true;
173 mutex_unlock(&data
->lock
);
176 if (on
&& (mask
& PA12203001_PX_EN_MASK
)) {
177 mutex_lock(&data
->lock
);
178 if (data
->als_enabled
) {
179 ret
= pa12203001_px_enable(data
, PA12203001_PX_EN_MASK
);
183 data
->px_needs_enable
= true;
185 mutex_unlock(&data
->lock
);
189 ret
= pm_runtime_get_sync(&data
->client
->dev
);
191 pm_runtime_put_noidle(&data
->client
->dev
);
194 pm_runtime_mark_last_busy(&data
->client
->dev
);
195 ret
= pm_runtime_put_autosuspend(&data
->client
->dev
);
201 mutex_unlock(&data
->lock
);
208 static int pa12203001_read_raw(struct iio_dev
*indio_dev
,
209 struct iio_chan_spec
const *chan
, int *val
,
210 int *val2
, long mask
)
212 struct pa12203001_data
*data
= iio_priv(indio_dev
);
215 unsigned int reg_byte
;
219 case IIO_CHAN_INFO_RAW
:
220 switch (chan
->type
) {
222 dev_mask
= PA12203001_ALS_EN_MASK
;
223 ret
= pa12203001_set_power_state(data
, true, dev_mask
);
227 * ALS ADC value is stored in registers
228 * PA12203001_REG_ADL and in PA12203001_REG_ADL + 1.
230 ret
= regmap_bulk_read(data
->map
, PA12203001_REG_ADL
,
235 *val
= le16_to_cpu(reg_word
);
236 ret
= pa12203001_set_power_state(data
, false, dev_mask
);
241 dev_mask
= PA12203001_PX_EN_MASK
;
242 ret
= pa12203001_set_power_state(data
, true, dev_mask
);
245 ret
= regmap_read(data
->map
, PA12203001_REG_PDH
,
251 ret
= pa12203001_set_power_state(data
, false, dev_mask
);
259 case IIO_CHAN_INFO_SCALE
:
260 ret
= regmap_read(data
->map
, PA12203001_REG_CFG0
, ®_byte
);
264 reg_byte
= (reg_byte
& PA12203001_AFSR_MASK
);
265 *val2
= pa12203001_scales
[reg_byte
>> 4];
266 return IIO_VAL_INT_PLUS_MICRO
;
272 pa12203001_set_power_state(data
, false, dev_mask
);
276 static int pa12203001_write_raw(struct iio_dev
*indio_dev
,
277 struct iio_chan_spec
const *chan
, int val
,
280 struct pa12203001_data
*data
= iio_priv(indio_dev
);
282 unsigned int reg_byte
;
285 case IIO_CHAN_INFO_SCALE
:
286 ret
= regmap_read(data
->map
, PA12203001_REG_CFG0
, ®_byte
);
287 if (val
!= 0 || ret
< 0)
289 for (i
= 0; i
< ARRAY_SIZE(pa12203001_scales
); i
++) {
290 if (val2
== pa12203001_scales
[i
]) {
291 new_val
= i
<< PA12203001_AFSR_SHIFT
;
292 return regmap_update_bits(data
->map
,
294 PA12203001_AFSR_MASK
,
306 static const struct iio_info pa12203001_info
= {
307 .read_raw
= pa12203001_read_raw
,
308 .write_raw
= pa12203001_write_raw
,
309 .attrs
= &pa12203001_attr_group
,
312 static int pa12203001_init(struct iio_dev
*indio_dev
)
314 struct pa12203001_data
*data
= iio_priv(indio_dev
);
317 for (i
= 0; i
< ARRAY_SIZE(regvals
); i
++) {
318 ret
= regmap_write(data
->map
, regvals
[i
].reg
, regvals
[i
].val
);
326 static int pa12203001_power_chip(struct iio_dev
*indio_dev
, u8 state
)
328 struct pa12203001_data
*data
= iio_priv(indio_dev
);
331 mutex_lock(&data
->lock
);
332 ret
= pa12203001_als_enable(data
, state
);
336 ret
= pa12203001_px_enable(data
, state
);
339 mutex_unlock(&data
->lock
);
343 static int pa12203001_probe(struct i2c_client
*client
,
344 const struct i2c_device_id
*id
)
346 struct pa12203001_data
*data
;
347 struct iio_dev
*indio_dev
;
350 indio_dev
= devm_iio_device_alloc(&client
->dev
,
351 sizeof(struct pa12203001_data
));
355 data
= iio_priv(indio_dev
);
356 i2c_set_clientdata(client
, indio_dev
);
357 data
->client
= client
;
359 data
->map
= devm_regmap_init_i2c(client
, &pa12203001_regmap_config
);
360 if (IS_ERR(data
->map
))
361 return PTR_ERR(data
->map
);
363 mutex_init(&data
->lock
);
365 indio_dev
->info
= &pa12203001_info
;
366 indio_dev
->name
= PA12203001_DRIVER_NAME
;
367 indio_dev
->channels
= pa12203001_channels
;
368 indio_dev
->num_channels
= ARRAY_SIZE(pa12203001_channels
);
369 indio_dev
->modes
= INDIO_DIRECT_MODE
;
371 ret
= pa12203001_init(indio_dev
);
375 ret
= pa12203001_power_chip(indio_dev
, PA12203001_CHIP_ENABLE
);
379 ret
= pm_runtime_set_active(&client
->dev
);
383 pm_runtime_enable(&client
->dev
);
384 pm_runtime_set_autosuspend_delay(&client
->dev
,
385 PA12203001_SLEEP_DELAY_MS
);
386 pm_runtime_use_autosuspend(&client
->dev
);
388 ret
= iio_device_register(indio_dev
);
395 pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
399 static int pa12203001_remove(struct i2c_client
*client
)
401 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
403 iio_device_unregister(indio_dev
);
405 pm_runtime_disable(&client
->dev
);
406 pm_runtime_set_suspended(&client
->dev
);
408 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
411 #if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM)
412 static int pa12203001_suspend(struct device
*dev
)
414 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
416 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_DISABLE
);
420 #ifdef CONFIG_PM_SLEEP
421 static int pa12203001_resume(struct device
*dev
)
423 struct iio_dev
*indio_dev
= i2c_get_clientdata(to_i2c_client(dev
));
425 return pa12203001_power_chip(indio_dev
, PA12203001_CHIP_ENABLE
);
430 static int pa12203001_runtime_resume(struct device
*dev
)
432 struct pa12203001_data
*data
;
434 data
= iio_priv(i2c_get_clientdata(to_i2c_client(dev
)));
436 mutex_lock(&data
->lock
);
437 if (data
->als_needs_enable
) {
438 pa12203001_als_enable(data
, PA12203001_ALS_EN_MASK
);
439 data
->als_needs_enable
= false;
441 if (data
->px_needs_enable
) {
442 pa12203001_px_enable(data
, PA12203001_PX_EN_MASK
);
443 data
->px_needs_enable
= false;
445 mutex_unlock(&data
->lock
);
451 static const struct dev_pm_ops pa12203001_pm_ops
= {
452 SET_SYSTEM_SLEEP_PM_OPS(pa12203001_suspend
, pa12203001_resume
)
453 SET_RUNTIME_PM_OPS(pa12203001_suspend
, pa12203001_runtime_resume
, NULL
)
456 static const struct acpi_device_id pa12203001_acpi_match
[] = {
461 MODULE_DEVICE_TABLE(acpi
, pa12203001_acpi_match
);
463 static const struct i2c_device_id pa12203001_id
[] = {
468 MODULE_DEVICE_TABLE(i2c
, pa12203001_id
);
470 static struct i2c_driver pa12203001_driver
= {
472 .name
= PA12203001_DRIVER_NAME
,
473 .pm
= &pa12203001_pm_ops
,
474 .acpi_match_table
= ACPI_PTR(pa12203001_acpi_match
),
476 .probe
= pa12203001_probe
,
477 .remove
= pa12203001_remove
,
478 .id_table
= pa12203001_id
,
481 module_i2c_driver(pa12203001_driver
);
483 MODULE_AUTHOR("Adriana Reus <adriana.reus@intel.com>");
484 MODULE_DESCRIPTION("Driver for TXC PA12203001 Proximity and Light Sensor");
485 MODULE_LICENSE("GPL v2");