File Index
Files and directories
Sign in
FILE

apds9160.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/light/apds9160.c C
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * APDS9160 sensor driver.
   4 * Chip is combined proximity and ambient light sensor.
   5 * Author: 2024 Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>
   6 */
   7
   8#include <linux/bits.h>
   9#include <linux/bitfield.h>
  10#include <linux/cleanup.h>
  11#include <linux/delay.h>
  12#include <linux/err.h>
  13#include <linux/i2c.h>
  14#include <linux/interrupt.h>
  15#include <linux/module.h>
  16#include <linux/mutex.h>
  17#include <linux/regmap.h>
  18#include <linux/regulator/consumer.h>
  19#include <linux/types.h>
  20#include <linux/units.h>
  21
  22#include <linux/iio/iio.h>
  23#include <linux/iio/events.h>
  24#include <linux/iio/sysfs.h>
  25
  26#include <linux/unaligned.h>
  27
  28/* Main control register */
  29#define APDS9160_REG_CTRL 0x00
  30#define APDS9160_CTRL_SWRESET BIT(4) /* 1: Activate reset */
  31#define APDS9160_CTRL_MODE_RGB BIT(2) /* 0: ALS & IR, 1: RGB & IR */
  32#define APDS9160_CTRL_EN_ALS BIT(1) /* 1: ALS active */
  33#define APDS9160_CTLR_EN_PS BIT(0) /* 1: PS active */
  34
  35/* Status register  */
  36#define APDS9160_SR_LS_INT BIT(4)
  37#define APDS9160_SR_LS_NEW_DATA BIT(3)
  38#define APDS9160_SR_PS_INT BIT(1)
  39#define APDS9160_SR_PS_NEW_DATA BIT(0)
  40
  41/* Interrupt configuration registers */
  42#define APDS9160_REG_INT_CFG 0x19
  43#define APDS9160_REG_INT_PST 0x1A
  44#define APDS9160_INT_CFG_EN_LS BIT(2) /* LS int enable */
  45#define APDS9160_INT_CFG_EN_PS BIT(0) /* PS int enable */
  46
  47/* Proximity registers */
  48#define APDS9160_REG_PS_LED 0x01
  49#define APDS9160_REG_PS_PULSES 0x02
  50#define APDS9160_REG_PS_MEAS_RATE 0x03
  51#define APDS9160_REG_PS_THRES_HI_LSB 0x1B
  52#define APDS9160_REG_PS_THRES_HI_MSB 0x1C
  53#define APDS9160_REG_PS_THRES_LO_LSB 0x1D
  54#define APDS9160_REG_PS_THRES_LO_MSB 0x1E
  55#define APDS9160_REG_PS_DATA_LSB 0x08
  56#define APDS9160_REG_PS_DATA_MSB 0x09
  57#define APDS9160_REG_PS_CAN_LEVEL_DIG_LSB 0x1F
  58#define APDS9160_REG_PS_CAN_LEVEL_DIG_MSB 0x20
  59#define APDS9160_REG_PS_CAN_LEVEL_ANA_DUR 0x21
  60#define APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT 0x22
  61
  62/* Light sensor registers */
  63#define APDS9160_REG_LS_MEAS_RATE 0x04
  64#define APDS9160_REG_LS_GAIN 0x05
  65#define APDS9160_REG_LS_DATA_CLEAR_LSB 0x0A
  66#define APDS9160_REG_LS_DATA_CLEAR 0x0B
  67#define APDS9160_REG_LS_DATA_CLEAR_MSB 0x0C
  68#define APDS9160_REG_LS_DATA_ALS_LSB 0x0D
  69#define APDS9160_REG_LS_DATA_ALS 0x0E
  70#define APDS9160_REG_LS_DATA_ALS_MSB 0x0F
  71#define APDS9160_REG_LS_THRES_UP_LSB 0x24
  72#define APDS9160_REG_LS_THRES_UP 0x25
  73#define APDS9160_REG_LS_THRES_UP_MSB 0x26
  74#define APDS9160_REG_LS_THRES_LO_LSB 0x27
  75#define APDS9160_REG_LS_THRES_LO 0x28
  76#define APDS9160_REG_LS_THRES_LO_MSB 0x29
  77#define APDS9160_REG_LS_THRES_VAR 0x2A
  78
  79/* Part identification number register */
  80#define APDS9160_REG_ID 0x06
  81
  82/* Status register */
  83#define APDS9160_REG_SR 0x07
  84#define APDS9160_SR_DATA_ALS BIT(3)
  85#define APDS9160_SR_DATA_PS BIT(0)
  86
  87/* Supported ID:s */
  88#define APDS9160_PART_ID_0 0x03
  89
  90#define APDS9160_PS_THRES_MAX 0x7FF
  91#define APDS9160_LS_THRES_MAX 0xFFFFF
  92#define APDS9160_CMD_LS_RESOLUTION_25MS 0x04
  93#define APDS9160_CMD_LS_RESOLUTION_50MS 0x03
  94#define APDS9160_CMD_LS_RESOLUTION_100MS 0x02
  95#define APDS9160_CMD_LS_RESOLUTION_200MS 0x01
  96#define APDS9160_PS_DATA_MASK 0x7FF
  97
  98#define APDS9160_DEFAULT_LS_GAIN 3
  99#define APDS9160_DEFAULT_LS_RATE 100
 100#define APDS9160_DEFAULT_PS_RATE 100
 101#define APDS9160_DEFAULT_PS_CANCELLATION_LEVEL 0
 102#define APDS9160_DEFAULT_PS_ANALOG_CANCELLATION 0
 103#define APDS9160_DEFAULT_PS_GAIN 1
 104#define APDS9160_DEFAULT_PS_CURRENT 100
 105#define APDS9160_DEFAULT_PS_RESOLUTION_11BITS 0x03
 106
 107static const struct reg_default apds9160_reg_defaults[] = {
 108	{ APDS9160_REG_CTRL, 0x00 }, /* Sensors disabled by default  */
 109	{ APDS9160_REG_PS_LED, 0x33 }, /* 60 kHz frequency, 100 mA */
 110	{ APDS9160_REG_PS_PULSES, 0x08 }, /* 8 pulses */
 111	{ APDS9160_REG_PS_MEAS_RATE, 0x05 }, /* 100ms */
 112	{ APDS9160_REG_LS_MEAS_RATE, 0x22 }, /* 100ms */
 113	{ APDS9160_REG_LS_GAIN, 0x01 }, /* 3x */
 114	{ APDS9160_REG_INT_CFG, 0x10 }, /* Interrupts disabled */
 115	{ APDS9160_REG_INT_PST, 0x00 },
 116	{ APDS9160_REG_PS_THRES_HI_LSB, 0xFF },
 117	{ APDS9160_REG_PS_THRES_HI_MSB, 0x07 },
 118	{ APDS9160_REG_PS_THRES_LO_LSB, 0x00 },
 119	{ APDS9160_REG_PS_THRES_LO_MSB, 0x00 },
 120	{ APDS9160_REG_PS_CAN_LEVEL_DIG_LSB, 0x00 },
 121	{ APDS9160_REG_PS_CAN_LEVEL_DIG_MSB, 0x00 },
 122	{ APDS9160_REG_PS_CAN_LEVEL_ANA_DUR, 0x00 },
 123	{ APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT, 0x00 },
 124	{ APDS9160_REG_LS_THRES_UP_LSB, 0xFF },
 125	{ APDS9160_REG_LS_THRES_UP, 0xFF },
 126	{ APDS9160_REG_LS_THRES_UP_MSB, 0x0F },
 127	{ APDS9160_REG_LS_THRES_LO_LSB, 0x00 },
 128	{ APDS9160_REG_LS_THRES_LO, 0x00 },
 129	{ APDS9160_REG_LS_THRES_LO_MSB, 0x00 },
 130	{ APDS9160_REG_LS_THRES_VAR, 0x00 },
 131};
 132
 133static const struct regmap_range apds9160_readable_ranges[] = {
 134	regmap_reg_range(APDS9160_REG_CTRL, APDS9160_REG_LS_THRES_VAR),
 135};
 136
 137static const struct regmap_access_table apds9160_readable_table = {
 138	.yes_ranges = apds9160_readable_ranges,
 139	.n_yes_ranges = ARRAY_SIZE(apds9160_readable_ranges),
 140};
 141
 142static const struct regmap_range apds9160_writeable_ranges[] = {
 143	regmap_reg_range(APDS9160_REG_CTRL, APDS9160_REG_LS_GAIN),
 144	regmap_reg_range(APDS9160_REG_INT_CFG, APDS9160_REG_LS_THRES_VAR),
 145};
 146
 147static const struct regmap_access_table apds9160_writeable_table = {
 148	.yes_ranges = apds9160_writeable_ranges,
 149	.n_yes_ranges = ARRAY_SIZE(apds9160_writeable_ranges),
 150};
 151
 152static const struct regmap_range apds9160_volatile_ranges[] = {
 153	regmap_reg_range(APDS9160_REG_SR, APDS9160_REG_LS_DATA_ALS_MSB),
 154};
 155
 156static const struct regmap_access_table apds9160_volatile_table = {
 157	.yes_ranges = apds9160_volatile_ranges,
 158	.n_yes_ranges = ARRAY_SIZE(apds9160_volatile_ranges),
 159};
 160
 161static const struct regmap_config apds9160_regmap_config = {
 162	.name = "apds9160_regmap",
 163	.reg_bits = 8,
 164	.val_bits = 8,
 165	.use_single_read = true,
 166	.use_single_write = true,
 167
 168	.rd_table = &apds9160_readable_table,
 169	.wr_table = &apds9160_writeable_table,
 170	.volatile_table = &apds9160_volatile_table,
 171
 172	.reg_defaults = apds9160_reg_defaults,
 173	.num_reg_defaults = ARRAY_SIZE(apds9160_reg_defaults),
 174	.max_register = 37,
 175	.cache_type = REGCACHE_RBTREE,
 176};
 177
 178static const struct iio_event_spec apds9160_event_spec[] = {
 179	{
 180		.type = IIO_EV_TYPE_THRESH,
 181		.dir = IIO_EV_DIR_RISING,
 182		.mask_separate = BIT(IIO_EV_INFO_VALUE),
 183	},
 184	{
 185		.type = IIO_EV_TYPE_THRESH,
 186		.dir = IIO_EV_DIR_FALLING,
 187		.mask_separate = BIT(IIO_EV_INFO_VALUE),
 188	},
 189	{
 190		.type = IIO_EV_TYPE_THRESH,
 191		.dir = IIO_EV_DIR_EITHER,
 192		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
 193	},
 194};
 195
 196static const struct iio_chan_spec apds9160_channels[] = {
 197	{
 198		/* Proximity sensor channel */
 199		.type = IIO_PROXIMITY,
 200		.address = APDS9160_REG_PS_DATA_LSB,
 201		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 202		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
 203					    BIT(IIO_CHAN_INFO_SCALE) |
 204					    BIT(IIO_CHAN_INFO_CALIBBIAS),
 205		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
 206						BIT(IIO_CHAN_INFO_SCALE),
 207		.event_spec = apds9160_event_spec,
 208		.num_event_specs = ARRAY_SIZE(apds9160_event_spec),
 209	},
 210	{
 211		/* Proximity sensor led current */
 212		.type = IIO_CURRENT,
 213		.output = 1,
 214		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 215		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
 216	},
 217	{
 218		/* Illuminance */
 219		.type = IIO_LIGHT,
 220		.address = APDS9160_REG_LS_DATA_ALS_LSB,
 221		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 222		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
 223					    BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
 224					    BIT(IIO_CHAN_INFO_SCALE),
 225		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
 226						BIT(IIO_CHAN_INFO_SCALE),
 227		.event_spec = apds9160_event_spec,
 228		.num_event_specs = ARRAY_SIZE(apds9160_event_spec),
 229	},
 230	{
 231		/* Clear channel */
 232		.type = IIO_INTENSITY,
 233		.address = APDS9160_REG_LS_DATA_CLEAR_LSB,
 234		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 235		.channel2 = IIO_MOD_LIGHT_CLEAR,
 236		.modified = 1,
 237	},
 238};
 239
 240static const struct iio_chan_spec apds9160_channels_without_events[] = {
 241	{
 242		/* Proximity sensor channel */
 243		.type = IIO_PROXIMITY,
 244		.address = APDS9160_REG_PS_DATA_LSB,
 245		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 246		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
 247					    BIT(IIO_CHAN_INFO_SCALE) |
 248					    BIT(IIO_CHAN_INFO_CALIBBIAS),
 249		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
 250						BIT(IIO_CHAN_INFO_SCALE),
 251	},
 252	{
 253		/* Proximity sensor led current */
 254		.type = IIO_CURRENT,
 255		.output = 1,
 256		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 257		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW),
 258	},
 259	{
 260		/* Illuminance */
 261		.type = IIO_LIGHT,
 262		.address = APDS9160_REG_LS_DATA_ALS_LSB,
 263		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 264		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_INT_TIME) |
 265					    BIT(IIO_CHAN_INFO_HARDWAREGAIN) |
 266					    BIT(IIO_CHAN_INFO_SCALE),
 267		.info_mask_separate_available = BIT(IIO_CHAN_INFO_INT_TIME) |
 268						BIT(IIO_CHAN_INFO_SCALE),
 269	},
 270	{
 271		/* Clear channel */
 272		.type = IIO_INTENSITY,
 273		.address = APDS9160_REG_LS_DATA_CLEAR_LSB,
 274		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
 275		.channel2 = IIO_MOD_LIGHT_CLEAR,
 276		.modified = 1,
 277	},
 278};
 279
 280static const int apds9160_als_rate_avail[] = {
 281	25, 50, 100, 200
 282};
 283
 284static const int apds9160_als_rate_map[][2] = {
 285	{ 25, 0x00 },
 286	{ 50, 0x01 },
 287	{ 100, 0x02 },
 288	{ 200, 0x03 },
 289};
 290
 291static const int apds9160_als_gain_map[][2] = {
 292	{ 1, 0x00 },
 293	{ 3, 0x01 },
 294	{ 6, 0x02 },
 295	{ 18, 0x03 },
 296	{ 54, 0x04 },
 297};
 298
 299static const int apds9160_ps_gain_avail[] = {
 300	1, 2, 4, 8
 301};
 302
 303static const int apds9160_ps_gain_map[][2] = {
 304	{ 1, 0x00 },
 305	{ 2, 0x01 },
 306	{ 4, 0x02 },
 307	{ 8, 0x03 },
 308};
 309
 310static const int apds9160_ps_rate_avail[] = {
 311	25, 50, 100, 200, 400
 312};
 313
 314static const int apds9160_ps_rate_map[][2] = {
 315	{ 25, 0x03 },
 316	{ 50, 0x04 },
 317	{ 100, 0x05 },
 318	{ 200, 0x06 },
 319	{ 400, 0x07 },
 320};
 321
 322static const int apds9160_ps_led_current_avail[] = {
 323	10, 25, 50, 100, 150, 175, 200
 324};
 325
 326static const int apds9160_ps_led_current_map[][2] = {
 327	{ 10, 0x00 },
 328	{ 25, 0x01 },
 329	{ 50, 0x02 },
 330	{ 100, 0x03 },
 331	{ 150, 0x04 },
 332	{ 175, 0x05 },
 333	{ 200, 0x06 },
 334};
 335
 336/**
 337 * struct apds9160_scale - apds9160 scale mapping definition
 338 *
 339 * @itime: Integration time in ms
 340 * @gain: Gain multiplier
 341 * @scale1: lux/count resolution
 342 * @scale2: micro lux/count
 343 */
 344struct apds9160_scale {
 345	int itime;
 346	int gain;
 347	int scale1;
 348	int scale2;
 349};
 350
 351/* Scale mapping extracted from datasheet */
 352static const struct apds9160_scale apds9160_als_scale_map[] = {
 353	{
 354		.itime = 25,
 355		.gain = 1,
 356		.scale1 = 3,
 357		.scale2 = 272000,
 358	},
 359	{
 360		.itime = 25,
 361		.gain = 3,
 362		.scale1 = 1,
 363		.scale2 = 77000,
 364	},
 365	{
 366		.itime = 25,
 367		.gain = 6,
 368		.scale1 = 0,
 369		.scale2 = 525000,
 370	},
 371	{
 372		.itime = 25,
 373		.gain = 18,
 374		.scale1 = 0,
 375		.scale2 = 169000,
 376	},
 377	{
 378		.itime = 25,
 379		.gain = 54,
 380		.scale1 = 0,
 381		.scale2 = 49000,
 382	},
 383	{
 384		.itime = 50,
 385		.gain = 1,
 386		.scale1 = 1,
 387		.scale2 = 639000,
 388	},
 389	{
 390		.itime = 50,
 391		.gain = 3,
 392		.scale1 = 0,
 393		.scale2 = 538000,
 394	},
 395	{
 396		.itime = 50,
 397		.gain = 6,
 398		.scale1 = 0,
 399		.scale2 = 263000,
 400	},
 401	{
 402		.itime = 50,
 403		.gain = 18,
 404		.scale1 = 0,
 405		.scale2 = 84000,
 406	},
 407	{
 408		.itime = 50,
 409		.gain = 54,
 410		.scale1 = 0,
 411		.scale2 = 25000,
 412	},
 413	{
 414		.itime = 100,
 415		.gain = 1,
 416		.scale1 = 0,
 417		.scale2 = 819000,
 418	},
 419	{
 420		.itime = 100,
 421		.gain = 3,
 422		.scale1 = 0,
 423		.scale2 = 269000,
 424	},
 425	{
 426		.itime = 100,
 427		.gain = 6,
 428		.scale1 = 0,
 429		.scale2 = 131000,
 430	},
 431	{
 432		.itime = 100,
 433		.gain = 18,
 434		.scale1 = 0,
 435		.scale2 = 42000,
 436	},
 437	{
 438		.itime = 100,
 439		.gain = 54,
 440		.scale1 = 0,
 441		.scale2 = 12000,
 442	},
 443	{
 444		.itime = 200,
 445		.gain = 1,
 446		.scale1 = 0,
 447		.scale2 = 409000,
 448	},
 449	{
 450		.itime = 200,
 451		.gain = 3,
 452		.scale1 = 0,
 453		.scale2 = 135000,
 454	},
 455	{
 456		.itime = 200,
 457		.gain = 6,
 458		.scale1 = 0,
 459		.scale2 = 66000,
 460	},
 461	{
 462		.itime = 200,
 463		.gain = 18,
 464		.scale1 = 0,
 465		.scale2 = 21000,
 466	},
 467	{
 468		.itime = 200,
 469		.gain = 54,
 470		.scale1 = 0,
 471		.scale2 = 6000,
 472	},
 473};
 474
 475static const int apds9160_25ms_avail[][2] = {
 476	{ 3, 272000 },
 477	{ 1, 77000 },
 478	{ 0, 525000 },
 479	{ 0, 169000 },
 480	{ 0, 49000 },
 481};
 482
 483static const int apds9160_50ms_avail[][2] = {
 484	{ 1, 639000 },
 485	{ 0, 538000 },
 486	{ 0, 263000 },
 487	{ 0, 84000 },
 488	{ 0, 25000 },
 489};
 490
 491static const int apds9160_100ms_avail[][2] = {
 492	{ 0, 819000 },
 493	{ 0, 269000 },
 494	{ 0, 131000 },
 495	{ 0, 42000 },
 496	{ 0, 12000 },
 497};
 498
 499static const int apds9160_200ms_avail[][2] = {
 500	{ 0, 409000 },
 501	{ 0, 135000 },
 502	{ 0, 66000 },
 503	{ 0, 21000 },
 504	{ 0, 6000 },
 505};
 506
 507static const struct reg_field apds9160_reg_field_ls_en =
 508	REG_FIELD(APDS9160_REG_CTRL, 1, 1);
 509
 510static const struct reg_field apds9160_reg_field_ps_en =
 511	REG_FIELD(APDS9160_REG_CTRL, 0, 0);
 512
 513static const struct reg_field apds9160_reg_field_int_ps =
 514	REG_FIELD(APDS9160_REG_INT_CFG, 0, 0);
 515
 516static const struct reg_field apds9160_reg_field_int_als =
 517	REG_FIELD(APDS9160_REG_INT_CFG, 2, 2);
 518
 519static const struct reg_field apds9160_reg_field_ps_overflow =
 520	REG_FIELD(APDS9160_REG_PS_DATA_MSB, 3, 3);
 521
 522static const struct reg_field apds9160_reg_field_als_rate =
 523	REG_FIELD(APDS9160_REG_LS_MEAS_RATE, 0, 2);
 524
 525static const struct reg_field apds9160_reg_field_als_gain =
 526	REG_FIELD(APDS9160_REG_LS_GAIN, 0, 2);
 527
 528static const struct reg_field apds9160_reg_field_ps_rate =
 529	REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 0, 2);
 530
 531static const struct reg_field apds9160_reg_field_als_res =
 532	REG_FIELD(APDS9160_REG_LS_MEAS_RATE, 4, 6);
 533
 534static const struct reg_field apds9160_reg_field_ps_current =
 535	REG_FIELD(APDS9160_REG_PS_LED, 0, 2);
 536
 537static const struct reg_field apds9160_reg_field_ps_gain =
 538	REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 6, 7);
 539
 540static const struct reg_field apds9160_reg_field_ps_resolution =
 541	REG_FIELD(APDS9160_REG_PS_MEAS_RATE, 3, 4);
 542
 543struct apds9160_chip {
 544	struct i2c_client *client;
 545	struct regmap *regmap;
 546
 547	struct regmap_field *reg_enable_ps;
 548	struct regmap_field *reg_enable_als;
 549	struct regmap_field *reg_int_ps;
 550	struct regmap_field *reg_int_als;
 551	struct regmap_field *reg_ps_overflow;
 552	struct regmap_field *reg_als_rate;
 553	struct regmap_field *reg_als_resolution;
 554	struct regmap_field *reg_ps_rate;
 555	struct regmap_field *reg_als_gain;
 556	struct regmap_field *reg_ps_current;
 557	struct regmap_field *reg_ps_gain;
 558	struct regmap_field *reg_ps_resolution;
 559
 560	struct mutex lock; /* protects state and config data */
 561
 562	/* State data */
 563	int als_int;
 564	int ps_int;
 565
 566	/* Configuration values */
 567	int als_itime;
 568	int als_hwgain;
 569	int als_scale1;
 570	int als_scale2;
 571	int ps_rate;
 572	int ps_cancellation_level;
 573	int ps_current;
 574	int ps_gain;
 575};
 576
 577static int apds9160_set_ps_rate(struct apds9160_chip *data, int val)
 578{
 579	int idx;
 580
 581	for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_rate_map); idx++) {
 582		int ret;
 583
 584		if (apds9160_ps_rate_map[idx][0] != val)
 585			continue;
 586
 587		ret = regmap_field_write(data->reg_ps_rate,
 588					apds9160_ps_rate_map[idx][1]);
 589		if (ret)
 590			return ret;
 591		data->ps_rate = val;
 592
 593		return ret;
 594	}
 595
 596	return -EINVAL;
 597}
 598
 599static int apds9160_set_ps_gain(struct apds9160_chip *data, int val)
 600{
 601	int idx;
 602
 603	for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_gain_map); idx++) {
 604		int ret;
 605
 606		if (apds9160_ps_gain_map[idx][0] != val)
 607			continue;
 608
 609		ret = regmap_field_write(data->reg_ps_gain,
 610					apds9160_ps_gain_map[idx][1]);
 611		if (ret)
 612			return ret;
 613		data->ps_gain = val;
 614
 615		return ret;
 616	}
 617
 618	return -EINVAL;
 619}
 620
 621/*
 622 * The PS intelligent cancellation level register allows
 623 * for an on-chip substraction of the ADC count caused by
 624 * unwanted reflected light from PS ADC output.
 625 */
 626static int apds9160_set_ps_cancellation_level(struct apds9160_chip *data,
 627					      int val)
 628{
 629	int ret;
 630	__le16 buf;
 631
 632	if (val < 0 || val > 0xFFFF)
 633		return -EINVAL;
 634
 635	buf = cpu_to_le16(val);
 636	ret = regmap_bulk_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_DIG_LSB,
 637				&buf, 2);
 638	if (ret)
 639		return ret;
 640
 641	data->ps_cancellation_level = val;
 642
 643	return ret;
 644}
 645
 646/*
 647 * This parameter determines the cancellation pulse duration
 648 * in each of the PWM pulse. The cancellation is applied during the
 649 * integration phase of the PS measurement.
 650 * Duration is programmed in half clock cycles
 651 * A duration value of 0 or 1 will not generate any cancellation pulse
 652 */
 653static int apds9160_set_ps_analog_cancellation(struct apds9160_chip *data,
 654					       int val)
 655{
 656	if (val < 0 || val > 63)
 657		return -EINVAL;
 658
 659	return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_DUR,
 660			   val);
 661}
 662
 663/*
 664 * This parameter works in conjunction with the cancellation pulse duration
 665 * The value determines the current used for crosstalk cancellation
 666 * Coarse value is in steps of 60 nA
 667 * Fine value is in steps of 2.4 nA
 668 */
 669static int apds9160_set_ps_cancellation_current(struct apds9160_chip *data,
 670						int coarse_val,
 671						int fine_val)
 672{
 673	int val;
 674
 675	if (coarse_val < 0 || coarse_val > 4)
 676		return -EINVAL;
 677
 678	if (fine_val < 0 || fine_val > 15)
 679		return -EINVAL;
 680
 681	/* Coarse value at B4:B5 and fine value at B0:B3 */
 682	val = (coarse_val << 4) | fine_val;
 683
 684	return regmap_write(data->regmap, APDS9160_REG_PS_CAN_LEVEL_ANA_CURRENT,
 685			    val);
 686}
 687
 688static int apds9160_ps_init_analog_cancellation(struct device *dev,
 689						struct apds9160_chip *data)
 690{
 691	int ret, duration, picoamp, idx, coarse, fine;
 692
 693	ret = device_property_read_u32(dev,
 694			"ps-cancellation-duration", &duration);
 695	if (ret || duration == 0) {
 696		/* Don't fail since this is not required */
 697		return 0;
 698	}
 699
 700	ret = device_property_read_u32(dev,
 701			"ps-cancellation-current-picoamp", &picoamp);
 702	if (ret)
 703		return ret;
 704
 705	if (picoamp < 60000 || picoamp > 276000 || picoamp % 2400 != 0)
 706		return dev_err_probe(dev, -EINVAL,
 707					"Invalid cancellation current\n");
 708
 709	/* Compute required coarse and fine value from requested current */
 710	fine = 0;
 711	coarse = 0;
 712	for (idx = 60000; idx < picoamp; idx += 2400) {
 713		if (fine == 15) {
 714			fine = 0;
 715			coarse++;
 716			idx += 21600;
 717		} else {
 718			fine++;
 719		}
 720	}
 721
 722	if (picoamp != idx)
 723		dev_warn(dev,
 724			"Invalid cancellation current %i, rounding to %i\n",
 725			picoamp, idx);
 726
 727	ret = apds9160_set_ps_analog_cancellation(data, duration);
 728	if (ret)
 729		return ret;
 730
 731	return apds9160_set_ps_cancellation_current(data, coarse, fine);
 732}
 733
 734static int apds9160_set_ps_current(struct apds9160_chip *data, int val)
 735{
 736	int idx;
 737
 738	for (idx = 0; idx < ARRAY_SIZE(apds9160_ps_led_current_map); idx++) {
 739		int ret;
 740
 741		if (apds9160_ps_led_current_map[idx][0] != val)
 742			continue;
 743
 744		ret = regmap_field_write(
 745				data->reg_ps_current,
 746				apds9160_ps_led_current_map[idx][1]);
 747		if (ret)
 748			return ret;
 749		data->ps_current = val;
 750
 751		return ret;
 752	}
 753
 754	return -EINVAL;
 755}
 756
 757static int apds9160_set_als_gain(struct apds9160_chip *data, int gain)
 758{
 759	int idx;
 760
 761	for (idx = 0; idx < ARRAY_SIZE(apds9160_als_gain_map); idx++) {
 762		int ret;
 763
 764		if (gain != apds9160_als_gain_map[idx][0])
 765			continue;
 766
 767		ret = regmap_field_write(data->reg_als_gain,
 768				apds9160_als_gain_map[idx][1]);
 769		if (ret)
 770			return ret;
 771		data->als_hwgain = gain;
 772
 773		return ret;
 774	}
 775
 776	return -EINVAL;
 777}
 778
 779static int apds9160_set_als_scale(struct apds9160_chip *data, int val, int val2)
 780{
 781	int idx;
 782
 783	for (idx = 0; idx < ARRAY_SIZE(apds9160_als_scale_map); idx++) {
 784		if (apds9160_als_scale_map[idx].itime == data->als_itime &&
 785		    apds9160_als_scale_map[idx].scale1 == val &&
 786		    apds9160_als_scale_map[idx].scale2 == val2) {
 787			int ret = apds9160_set_als_gain(data,
 788					apds9160_als_scale_map[idx].gain);
 789			if (ret)
 790				return ret;
 791			data->als_scale1 = val;
 792			data->als_scale2 = val2;
 793
 794			return ret;
 795		}
 796	}
 797
 798	return -EINVAL;
 799}
 800
 801static int apds9160_set_als_resolution(struct apds9160_chip *data, int val)
 802{
 803	switch (val) {
 804	case 25:
 805		return regmap_field_write(data->reg_als_resolution,
 806			APDS9160_CMD_LS_RESOLUTION_25MS);
 807	case 50:
 808		return regmap_field_write(data->reg_als_resolution,
 809			APDS9160_CMD_LS_RESOLUTION_50MS);
 810	case 200:
 811		return regmap_field_write(data->reg_als_resolution,
 812			APDS9160_CMD_LS_RESOLUTION_200MS);
 813	default:
 814		return regmap_field_write(data->reg_als_resolution,
 815			APDS9160_CMD_LS_RESOLUTION_100MS);
 816	}
 817}
 818
 819static int apds9160_set_als_rate(struct apds9160_chip *data, int val)
 820{
 821	int idx;
 822
 823	for (idx = 0; idx < ARRAY_SIZE(apds9160_als_rate_map); idx++) {
 824		if (apds9160_als_rate_map[idx][0] != val)
 825			continue;
 826
 827		return regmap_field_write(data->reg_als_rate,
 828				apds9160_als_rate_map[idx][1]);
 829	}
 830
 831	return -EINVAL;
 832}
 833
 834/*
 835 * Setting the integration time ajusts resolution, rate, scale and gain
 836 */
 837static int apds9160_set_als_int_time(struct apds9160_chip *data, int val)
 838{
 839	int ret;
 840	int idx;
 841
 842	ret = apds9160_set_als_rate(data, val);
 843	if (ret)
 844		return ret;
 845
 846	/* Match resolution register with rate */
 847	ret = apds9160_set_als_resolution(data, val);
 848	if (ret)
 849		return ret;
 850
 851	data->als_itime = val;
 852
 853	/* Set the scale minimum gain */
 854	for (idx = 0; idx < ARRAY_SIZE(apds9160_als_scale_map); idx++) {
 855		if (data->als_itime != apds9160_als_scale_map[idx].itime)
 856			continue;
 857
 858		return apds9160_set_als_scale(data,
 859				apds9160_als_scale_map[idx].scale1,
 860				apds9160_als_scale_map[idx].scale2);
 861	}
 862
 863	return -EINVAL;
 864}
 865
 866static int apds9160_read_avail(struct iio_dev *indio_dev,
 867			       struct iio_chan_spec const *chan,
 868			       const int **vals, int *type, int *length,
 869			       long mask)
 870{
 871	struct apds9160_chip *data = iio_priv(indio_dev);
 872
 873	switch (mask) {
 874	case IIO_CHAN_INFO_INT_TIME:
 875		switch (chan->type) {
 876		case IIO_LIGHT:
 877			*length = ARRAY_SIZE(apds9160_als_rate_avail);
 878			*vals = (const int *)apds9160_als_rate_avail;
 879			*type = IIO_VAL_INT;
 880
 881			return IIO_AVAIL_LIST;
 882		case IIO_PROXIMITY:
 883			*length = ARRAY_SIZE(apds9160_ps_rate_avail);
 884			*vals = (const int *)apds9160_ps_rate_avail;
 885			*type = IIO_VAL_INT;
 886
 887			return IIO_AVAIL_LIST;
 888		default:
 889			return -EINVAL;
 890		}
 891	case IIO_CHAN_INFO_SCALE:
 892		switch (chan->type) {
 893		case IIO_PROXIMITY:
 894			*length = ARRAY_SIZE(apds9160_ps_gain_avail);
 895			*vals = (const int *)apds9160_ps_gain_avail;
 896			*type = IIO_VAL_INT;
 897
 898			return IIO_AVAIL_LIST;
 899		case IIO_LIGHT:
 900			/* The available scales changes depending on itime */
 901			switch (data->als_itime) {
 902			case 25:
 903				*length = ARRAY_SIZE(apds9160_25ms_avail) * 2;
 904				*vals = (const int *)apds9160_25ms_avail;
 905				*type = IIO_VAL_INT_PLUS_MICRO;
 906
 907				return IIO_AVAIL_LIST;
 908			case 50:
 909				*length = ARRAY_SIZE(apds9160_50ms_avail) * 2;
 910				*vals = (const int *)apds9160_50ms_avail;
 911				*type = IIO_VAL_INT_PLUS_MICRO;
 912
 913				return IIO_AVAIL_LIST;
 914			case 100:
 915				*length = ARRAY_SIZE(apds9160_100ms_avail) * 2;
 916				*vals = (const int *)apds9160_100ms_avail;
 917				*type = IIO_VAL_INT_PLUS_MICRO;
 918
 919				return IIO_AVAIL_LIST;
 920			case 200:
 921				*length = ARRAY_SIZE(apds9160_200ms_avail) * 2;
 922				*vals = (const int *)apds9160_200ms_avail;
 923				*type = IIO_VAL_INT_PLUS_MICRO;
 924
 925				return IIO_AVAIL_LIST;
 926			default:
 927				return -EINVAL;
 928			}
 929		default:
 930			return -EINVAL;
 931		}
 932	case IIO_CHAN_INFO_RAW:
 933		switch (chan->type) {
 934		case IIO_CURRENT:
 935			*length = ARRAY_SIZE(apds9160_ps_led_current_avail);
 936			*vals = (const int *)apds9160_ps_led_current_avail;
 937			*type = IIO_VAL_INT;
 938
 939			return IIO_AVAIL_LIST;
 940		default:
 941			return -EINVAL;
 942		}
 943
 944	default:
 945		return -EINVAL;
 946	}
 947}
 948
 949static int apds9160_write_raw_get_fmt(struct iio_dev *indio_dev,
 950				      struct iio_chan_spec const *chan,
 951				      long mask)
 952{
 953	switch (mask) {
 954	case IIO_CHAN_INFO_INT_TIME:
 955		return IIO_VAL_INT;
 956	case IIO_CHAN_INFO_CALIBBIAS:
 957		return IIO_VAL_INT;
 958	case IIO_CHAN_INFO_HARDWAREGAIN:
 959		return IIO_VAL_INT;
 960	case IIO_CHAN_INFO_RAW:
 961		return IIO_VAL_INT;
 962	case IIO_CHAN_INFO_SCALE:
 963		return IIO_VAL_INT_PLUS_MICRO;
 964	default:
 965		return -EINVAL;
 966	}
 967}
 968
 969static int apds9160_read_raw(struct iio_dev *indio_dev,
 970			     struct iio_chan_spec const *chan, int *val,
 971			     int *val2, long mask)
 972{
 973	struct apds9160_chip *data = iio_priv(indio_dev);
 974	int ret;
 975
 976	switch (mask) {
 977	case IIO_CHAN_INFO_RAW:
 978		switch (chan->type) {
 979		case IIO_PROXIMITY: {
 980			__le16 buf;
 981
 982			ret = regmap_bulk_read(data->regmap, chan->address,
 983					       &buf, 2);
 984			if (ret)
 985				return ret;
 986			*val = le16_to_cpu(buf);
 987			/* Remove overflow bits from result */
 988			*val = FIELD_GET(APDS9160_PS_DATA_MASK, *val);
 989
 990			return IIO_VAL_INT;
 991		}
 992		case IIO_LIGHT:
 993		case IIO_INTENSITY: {
 994			u8 buf[3];
 995
 996			ret = regmap_bulk_read(data->regmap, chan->address,
 997					       &buf, 3);
 998			if (ret)
 999				return ret;
1000			*val = get_unaligned_le24(buf);
1001
1002			return IIO_VAL_INT;
1003		}
1004		case IIO_CURRENT:
1005			*val = data->ps_current;
1006
1007			return IIO_VAL_INT;
1008		default:
1009			return -EINVAL;
1010		}
1011	case IIO_CHAN_INFO_HARDWAREGAIN:
1012		switch (chan->type) {
1013		case IIO_LIGHT:
1014			*val = data->als_hwgain;
1015
1016			return IIO_VAL_INT;
1017		default:
1018			return -EINVAL;
1019		}
1020	case IIO_CHAN_INFO_INT_TIME:
1021		switch (chan->type) {
1022		case IIO_PROXIMITY:
1023			*val = data->ps_rate;
1024
1025			return IIO_VAL_INT;
1026		case IIO_LIGHT:
1027			*val = data->als_itime;
1028
1029			return IIO_VAL_INT;
1030		default:
1031			return -EINVAL;
1032		}
1033	case IIO_CHAN_INFO_CALIBBIAS:
1034		switch (chan->type) {
1035		case IIO_PROXIMITY:
1036			*val = data->ps_cancellation_level;
1037
1038			return IIO_VAL_INT;
1039		default:
1040			return -EINVAL;
1041		}
1042	case IIO_CHAN_INFO_SCALE:
1043		switch (chan->type) {
1044		case IIO_PROXIMITY:
1045			*val = data->ps_gain;
1046
1047			return IIO_VAL_INT;
1048		case IIO_LIGHT:
1049			*val = data->als_scale1;
1050			*val2 = data->als_scale2;
1051
1052			return IIO_VAL_INT_PLUS_MICRO;
1053		default:
1054			return -EINVAL;
1055		}
1056	default:
1057		return -EINVAL;
1058	}
1059};
1060
1061static int apds9160_write_raw(struct iio_dev *indio_dev,
1062			      struct iio_chan_spec const *chan, int val,
1063			      int val2, long mask)
1064{
1065	struct apds9160_chip *data = iio_priv(indio_dev);
1066
1067	guard(mutex)(&data->lock);
1068
1069	switch (mask) {
1070	case IIO_CHAN_INFO_INT_TIME:
1071		if (val2 != 0)
1072			return -EINVAL;
1073		switch (chan->type) {
1074		case IIO_PROXIMITY:
1075			return apds9160_set_ps_rate(data, val);
1076		case IIO_LIGHT:
1077			return apds9160_set_als_int_time(data, val);
1078		default:
1079			return -EINVAL;
1080		}
1081	case IIO_CHAN_INFO_SCALE:
1082		switch (chan->type) {
1083		case IIO_PROXIMITY:
1084			return apds9160_set_ps_gain(data, val);
1085		case IIO_LIGHT:
1086			return apds9160_set_als_scale(data, val, val2);
1087		default:
1088			return -EINVAL;
1089		}
1090	case IIO_CHAN_INFO_CALIBBIAS:
1091		if (val2 != 0)
1092			return -EINVAL;
1093		switch (chan->type) {
1094		case IIO_PROXIMITY:
1095			return apds9160_set_ps_cancellation_level(data, val);
1096		default:
1097			return -EINVAL;
1098		}
1099	case IIO_CHAN_INFO_RAW:
1100		if (val2 != 0)
1101			return -EINVAL;
1102		switch (chan->type) {
1103		case IIO_CURRENT:
1104			return apds9160_set_ps_current(data, val);
1105		default:
1106			return -EINVAL;
1107		}
1108	default:
1109		return -EINVAL;
1110	}
1111}
1112
1113static inline int apds9160_get_thres_reg(const struct iio_chan_spec *chan,
1114					 enum iio_event_direction dir, u8 *reg)
1115{
1116	switch (dir) {
1117	case IIO_EV_DIR_RISING:
1118		switch (chan->type) {
1119		case IIO_PROXIMITY:
1120			*reg = APDS9160_REG_PS_THRES_HI_LSB;
1121			break;
1122		case IIO_LIGHT:
1123			*reg = APDS9160_REG_LS_THRES_UP_LSB;
1124			break;
1125		default:
1126			return -EINVAL;
1127		} break;
1128	case IIO_EV_DIR_FALLING:
1129		switch (chan->type) {
1130		case IIO_PROXIMITY:
1131			*reg = APDS9160_REG_PS_THRES_LO_LSB;
1132			break;
1133		case IIO_LIGHT:
1134			*reg = APDS9160_REG_LS_THRES_LO_LSB;
1135			break;
1136		default:
1137			return -EINVAL;
1138		}
1139		break;
1140	default:
1141		return -EINVAL;
1142	}
1143
1144	return 0;
1145}
1146
1147static int apds9160_read_event(struct iio_dev *indio_dev,
1148			       const struct iio_chan_spec *chan,
1149			       enum iio_event_type type,
1150			       enum iio_event_direction dir,
1151			       enum iio_event_info info, int *val, int *val2)
1152{
1153	u8 reg;
1154	int ret;
1155	struct apds9160_chip *data = iio_priv(indio_dev);
1156
1157	if (info != IIO_EV_INFO_VALUE)
1158		return -EINVAL;
1159
1160	ret = apds9160_get_thres_reg(chan, dir, &reg);
1161	if (ret < 0)
1162		return ret;
1163
1164	switch (chan->type) {
1165	case IIO_PROXIMITY: {
1166		__le16 buf;
1167
1168		ret = regmap_bulk_read(data->regmap, reg, &buf, 2);
1169		if (ret < 0)
1170			return ret;
1171		*val = le16_to_cpu(buf);
1172		return IIO_VAL_INT;
1173	}
1174	case IIO_LIGHT: {
1175		u8 buf[3];
1176
1177		ret = regmap_bulk_read(data->regmap, reg, &buf, 3);
1178		if (ret < 0)
1179			return ret;
1180		*val = get_unaligned_le24(buf);
1181		return IIO_VAL_INT;
1182	}
1183	default:
1184		return -EINVAL;
1185	}
1186}
1187
1188static int apds9160_write_event(struct iio_dev *indio_dev,
1189				const struct iio_chan_spec *chan,
1190				enum iio_event_type type,
1191				enum iio_event_direction dir,
1192				enum iio_event_info info, int val, int val2)
1193{
1194	u8 reg;
1195	int ret = 0;
1196	struct apds9160_chip *data = iio_priv(indio_dev);
1197
1198	if (info != IIO_EV_INFO_VALUE)
1199		return -EINVAL;
1200
1201	ret = apds9160_get_thres_reg(chan, dir, &reg);
1202	if (ret < 0)
1203		return ret;
1204
1205	switch (chan->type) {
1206	case IIO_PROXIMITY: {
1207		__le16 buf;
1208
1209		if (val < 0 || val > APDS9160_PS_THRES_MAX)
1210			return -EINVAL;
1211
1212		buf = cpu_to_le16(val);
1213		return regmap_bulk_write(data->regmap, reg, &buf, 2);
1214	}
1215	case IIO_LIGHT: {
1216		u8 buf[3];
1217
1218		if (val < 0 || val > APDS9160_LS_THRES_MAX)
1219			return -EINVAL;
1220
1221		put_unaligned_le24(val, buf);
1222		return regmap_bulk_write(data->regmap, reg, &buf, 3);
1223	}
1224	default:
1225		return -EINVAL;
1226	}
1227}
1228
1229static int apds9160_read_event_config(struct iio_dev *indio_dev,
1230				      const struct iio_chan_spec *chan,
1231				      enum iio_event_type type,
1232				      enum iio_event_direction dir)
1233{
1234	struct apds9160_chip *data = iio_priv(indio_dev);
1235
1236	switch (chan->type) {
1237	case IIO_PROXIMITY:
1238		return data->ps_int;
1239	case IIO_LIGHT:
1240		return data->als_int;
1241	default:
1242		return -EINVAL;
1243	}
1244}
1245
1246static int apds9160_write_event_config(struct iio_dev *indio_dev,
1247				       const struct iio_chan_spec *chan,
1248				       enum iio_event_type type,
1249				       enum iio_event_direction dir, bool state)
1250{
1251	struct apds9160_chip *data = iio_priv(indio_dev);
1252	int ret;
1253
1254	switch (chan->type) {
1255	case IIO_PROXIMITY:
1256		ret = regmap_field_write(data->reg_int_ps, state);
1257		if (ret)
1258			return ret;
1259		data->ps_int = state;
1260
1261		return 0;
1262	case IIO_LIGHT:
1263		ret = regmap_field_write(data->reg_int_als, state);
1264		if (ret)
1265			return ret;
1266		data->als_int = state;
1267
1268		return 0;
1269	default:
1270		return -EINVAL;
1271	}
1272}
1273
1274static irqreturn_t apds9160_irq_handler(int irq, void *private)
1275{
1276	struct iio_dev *indio_dev = private;
1277	struct apds9160_chip *data = iio_priv(indio_dev);
1278	int ret, status;
1279
1280	/* Reading status register clears the interrupt flag */
1281	ret = regmap_read(data->regmap, APDS9160_REG_SR, &status);
1282	if (ret < 0) {
1283		dev_err_ratelimited(&data->client->dev,
1284				    "irq status reg read failed\n");
1285		return IRQ_HANDLED;
1286	}
1287
1288	if ((status & APDS9160_SR_LS_INT) &&
1289	    (status & APDS9160_SR_LS_NEW_DATA) && data->als_int) {
1290		iio_push_event(indio_dev,
1291			       IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
1292						    IIO_EV_TYPE_THRESH,
1293						    IIO_EV_DIR_EITHER),
1294			       iio_get_time_ns(indio_dev));
1295	}
1296
1297	if ((status & APDS9160_SR_PS_INT) &&
1298	    (status & APDS9160_SR_PS_NEW_DATA) && data->ps_int) {
1299		iio_push_event(indio_dev,
1300			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
1301						    IIO_EV_TYPE_THRESH,
1302						    IIO_EV_DIR_EITHER),
1303			       iio_get_time_ns(indio_dev));
1304	}
1305
1306	return IRQ_HANDLED;
1307}
1308
1309static int apds9160_detect(struct apds9160_chip *chip)
1310{
1311	struct i2c_client *client = chip->client;
1312	int ret;
1313	u32 val;
1314
1315	ret = regmap_read(chip->regmap, APDS9160_REG_ID, &val);
1316	if (ret < 0) {
1317		dev_err(&client->dev, "ID read failed\n");
1318		return ret;
1319	}
1320
1321	if (val != APDS9160_PART_ID_0)
1322		dev_info(&client->dev, "Unknown part id %u\n", val);
1323
1324	return 0;
1325}
1326
1327static void apds9160_disable(void *chip)
1328{
1329	struct apds9160_chip *data = chip;
1330	int ret;
1331
1332	ret = regmap_field_write(data->reg_enable_als, 0);
1333	if (ret)
1334		return;
1335
1336	regmap_field_write(data->reg_enable_ps, 0);
1337}
1338
1339static int apds9160_chip_init(struct apds9160_chip *chip)
1340{
1341	int ret;
1342
1343	/* Write default values to interrupt register */
1344	ret = regmap_field_write(chip->reg_int_ps, 0);
1345	chip->ps_int = 0;
1346	if (ret)
1347		return ret;
1348
1349	ret = regmap_field_write(chip->reg_int_als, 0);
1350	chip->als_int = 0;
1351	if (ret)
1352		return ret;
1353
1354	/* Write default values to control register */
1355	ret = regmap_field_write(chip->reg_enable_als, 1);
1356	if (ret)
1357		return ret;
1358
1359	ret = regmap_field_write(chip->reg_enable_ps, 1);
1360	if (ret)
1361		return ret;
1362
1363	/* Write other default values */
1364	ret = regmap_field_write(chip->reg_ps_resolution,
1365				 APDS9160_DEFAULT_PS_RESOLUTION_11BITS);
1366	if (ret)
1367		return ret;
1368
1369	/* Write default values to configuration registers */
1370	ret = apds9160_set_ps_current(chip, APDS9160_DEFAULT_PS_CURRENT);
1371	if (ret)
1372		return ret;
1373
1374	ret = apds9160_set_ps_rate(chip, APDS9160_DEFAULT_PS_RATE);
1375	if (ret)
1376		return ret;
1377
1378	ret = apds9160_set_als_int_time(chip, APDS9160_DEFAULT_LS_RATE);
1379	if (ret)
1380		return ret;
1381
1382	ret = apds9160_set_als_scale(chip,
1383				     apds9160_100ms_avail[0][0],
1384				     apds9160_100ms_avail[0][1]);
1385	if (ret)
1386		return ret;
1387
1388	ret = apds9160_set_ps_gain(chip, APDS9160_DEFAULT_PS_GAIN);
1389	if (ret)
1390		return ret;
1391
1392	ret = apds9160_set_ps_analog_cancellation(
1393		chip, APDS9160_DEFAULT_PS_ANALOG_CANCELLATION);
1394	if (ret)
1395		return ret;
1396
1397	ret = apds9160_set_ps_cancellation_level(
1398		chip, APDS9160_DEFAULT_PS_CANCELLATION_LEVEL);
1399	if (ret)
1400		return ret;
1401
1402	return devm_add_action_or_reset(&chip->client->dev, apds9160_disable,
1403					chip);
1404}
1405
1406static int apds9160_regfield_init(struct apds9160_chip *data)
1407{
1408	struct device *dev = &data->client->dev;
1409	struct regmap *regmap = data->regmap;
1410	struct regmap_field *tmp;
1411
1412	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_int_als);
1413	if (IS_ERR(tmp))
1414		return PTR_ERR(tmp);
1415	data->reg_int_als = tmp;
1416
1417	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_int_ps);
1418	if (IS_ERR(tmp))
1419		return PTR_ERR(tmp);
1420	data->reg_int_ps = tmp;
1421
1422	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ls_en);
1423	if (IS_ERR(tmp))
1424		return PTR_ERR(tmp);
1425	data->reg_enable_als = tmp;
1426
1427	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_en);
1428	if (IS_ERR(tmp))
1429		return PTR_ERR(tmp);
1430	data->reg_enable_ps = tmp;
1431
1432	tmp = devm_regmap_field_alloc(dev, regmap,
1433				      apds9160_reg_field_ps_overflow);
1434	if (IS_ERR(tmp))
1435		return PTR_ERR(tmp);
1436	data->reg_ps_overflow = tmp;
1437
1438	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_rate);
1439	if (IS_ERR(tmp))
1440		return PTR_ERR(tmp);
1441	data->reg_als_rate = tmp;
1442
1443	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_res);
1444	if (IS_ERR(tmp))
1445		return PTR_ERR(tmp);
1446	data->reg_als_resolution = tmp;
1447
1448	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_rate);
1449	if (IS_ERR(tmp))
1450		return PTR_ERR(tmp);
1451	data->reg_ps_rate = tmp;
1452
1453	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_als_gain);
1454	if (IS_ERR(tmp))
1455		return PTR_ERR(tmp);
1456	data->reg_als_gain = tmp;
1457
1458	tmp = devm_regmap_field_alloc(dev, regmap,
1459				      apds9160_reg_field_ps_current);
1460	if (IS_ERR(tmp))
1461		return PTR_ERR(tmp);
1462	data->reg_ps_current = tmp;
1463
1464	tmp = devm_regmap_field_alloc(dev, regmap, apds9160_reg_field_ps_gain);
1465	if (IS_ERR(tmp))
1466		return PTR_ERR(tmp);
1467	data->reg_ps_gain = tmp;
1468
1469	tmp = devm_regmap_field_alloc(dev, regmap,
1470				      apds9160_reg_field_ps_resolution);
1471	if (IS_ERR(tmp))
1472		return PTR_ERR(tmp);
1473	data->reg_ps_resolution = tmp;
1474
1475	return 0;
1476}
1477
1478static const struct iio_info apds9160_info = {
1479	.read_avail = apds9160_read_avail,
1480	.read_raw = apds9160_read_raw,
1481	.write_raw = apds9160_write_raw,
1482	.write_raw_get_fmt = apds9160_write_raw_get_fmt,
1483	.read_event_value = apds9160_read_event,
1484	.write_event_value = apds9160_write_event,
1485	.read_event_config = apds9160_read_event_config,
1486	.write_event_config = apds9160_write_event_config,
1487};
1488
1489static const struct iio_info apds9160_info_no_events = {
1490	.read_avail = apds9160_read_avail,
1491	.read_raw = apds9160_read_raw,
1492	.write_raw = apds9160_write_raw,
1493	.write_raw_get_fmt = apds9160_write_raw_get_fmt,
1494};
1495
1496static int apds9160_probe(struct i2c_client *client)
1497{
1498	struct device *dev = &client->dev;
1499	struct apds9160_chip *chip;
1500	struct iio_dev *indio_dev;
1501	int ret;
1502
1503	indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
1504	if (!indio_dev)
1505		return -ENOMEM;
1506
1507	ret = devm_regulator_get_enable(dev, "vdd");
1508	if (ret)
1509		return dev_err_probe(dev, ret, "Failed to enable vdd supply\n");
1510
1511	indio_dev->name = "apds9160";
1512	indio_dev->modes = INDIO_DIRECT_MODE;
1513
1514	chip = iio_priv(indio_dev);
1515	chip->client = client;
1516	chip->regmap = devm_regmap_init_i2c(client, &apds9160_regmap_config);
1517	if (IS_ERR(chip->regmap))
1518		return dev_err_probe(dev, PTR_ERR(chip->regmap),
1519				     "regmap initialization failed.\n");
1520
1521	chip->client = client;
1522	mutex_init(&chip->lock);
1523
1524	ret = apds9160_detect(chip);
1525	if (ret < 0)
1526		return dev_err_probe(dev, ret, "apds9160 not found\n");
1527
1528	ret = apds9160_regfield_init(chip);
1529	if (ret)
1530		return ret;
1531
1532	ret = apds9160_chip_init(chip);
1533	if (ret)
1534		return ret;
1535
1536	ret = apds9160_ps_init_analog_cancellation(dev, chip);
1537	if (ret)
1538		return ret;
1539
1540	if (client->irq > 0) {
1541		indio_dev->info = &apds9160_info;
1542		indio_dev->channels = apds9160_channels;
1543		indio_dev->num_channels = ARRAY_SIZE(apds9160_channels);
1544		ret = devm_request_threaded_irq(dev, client->irq, NULL,
1545						apds9160_irq_handler,
1546						IRQF_ONESHOT, "apds9160_event",
1547						indio_dev);
1548		if (ret) {
1549			return dev_err_probe(dev, ret,
1550					     "request irq (%d) failed\n",
1551					     client->irq);
1552		}
1553	} else {
1554		indio_dev->info = &apds9160_info_no_events;
1555		indio_dev->channels = apds9160_channels_without_events;
1556		indio_dev->num_channels =
1557			ARRAY_SIZE(apds9160_channels_without_events);
1558	}
1559
1560	ret = devm_iio_device_register(dev, indio_dev);
1561	if (ret)
1562		return dev_err_probe(dev, ret,
1563				     "failed iio device registration\n");
1564
1565	return ret;
1566}
1567
1568static const struct of_device_id apds9160_of_match[] = {
1569	{ .compatible = "brcm,apds9160" },
1570	{ }
1571};
1572MODULE_DEVICE_TABLE(of, apds9160_of_match);
1573
1574static const struct i2c_device_id apds9160_id[] = {
1575	{ "apds9160", 0 },
1576	{ }
1577};
1578MODULE_DEVICE_TABLE(i2c, apds9160_id);
1579
1580static struct i2c_driver apds9160_driver = {
1581	.driver	  = {
1582		.name	= "apds9160",
1583		.of_match_table = apds9160_of_match,
1584	},
1585	.probe    = apds9160_probe,
1586	.id_table = apds9160_id,
1587};
1588module_i2c_driver(apds9160_driver);
1589
1590MODULE_DESCRIPTION("APDS9160 combined ALS and proximity sensor");
1591MODULE_AUTHOR("Mikael Gonella-Bolduc <m.gonella.bolduc@gmail.com>");
1592MODULE_LICENSE("GPL");
~/ Read-only file preview.