^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This file is part of the APDS990x sensor driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Chip is combined proximity and ambient light sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/platform_data/apds990x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Register map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define APDS990X_ENABLE 0x00 /* Enable of states and interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define APDS990X_ATIME 0x01 /* ALS ADC time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define APDS990X_PTIME 0x02 /* Proximity ADC time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define APDS990X_WTIME 0x03 /* Wait time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define APDS990X_AILTL 0x04 /* ALS interrupt low threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define APDS990X_AILTH 0x05 /* ALS interrupt low threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define APDS990X_AIHTL 0x06 /* ALS interrupt hi threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define APDS990X_AIHTH 0x07 /* ALS interrupt hi threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define APDS990X_PILTL 0x08 /* Proximity interrupt low threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define APDS990X_PILTH 0x09 /* Proximity interrupt low threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define APDS990X_PIHTL 0x0a /* Proximity interrupt hi threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define APDS990X_PIHTH 0x0b /* Proximity interrupt hi threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define APDS990X_PERS 0x0c /* Interrupt persistence filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define APDS990X_CONFIG 0x0d /* Configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define APDS990X_PPCOUNT 0x0e /* Proximity pulse count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define APDS990X_CONTROL 0x0f /* Gain control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define APDS990X_REV 0x11 /* Revision Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define APDS990X_ID 0x12 /* Device ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define APDS990X_STATUS 0x13 /* Device status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define APDS990X_CDATAL 0x14 /* Clear ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define APDS990X_CDATAH 0x15 /* Clear ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define APDS990X_IRDATAL 0x16 /* IR ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define APDS990X_IRDATAH 0x17 /* IR ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define APDS990X_PDATAL 0x18 /* Proximity ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define APDS990X_PDATAH 0x19 /* Proximity ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define APDS990X_MAX_AGAIN 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* Enable register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define APDS990X_EN_PIEN (0x1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define APDS990X_EN_AIEN (0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define APDS990X_EN_WEN (0x1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define APDS990X_EN_PEN (0x1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define APDS990X_EN_AEN (0x1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define APDS990X_EN_PON (0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define APDS990X_EN_DISABLE_ALL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define APDS990X_ST_PINT (0x1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define APDS990X_ST_AINT (0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* I2C access types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define APDS990x_CMD_TYPE_MASK (0x03 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define APDS990x_CMD_TYPE_RB (0x00 << 5) /* Repeated byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define APDS990x_CMD_TYPE_INC (0x01 << 5) /* Auto increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define APDS990x_CMD_TYPE_SPE (0x03 << 5) /* Special function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define APDS990x_ADDR_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define APDS990x_CMD 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Interrupt ack commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define APDS990X_INT_ACK_ALS 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define APDS990X_INT_ACK_PS 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define APDS990X_INT_ACK_BOTH 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* ptime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define APDS990X_PTIME_DEFAULT 0xff /* Recommended conversion time 2.7ms*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* wtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define APDS990X_WTIME_DEFAULT 0xee /* ~50ms wait time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define APDS990X_TIME_TO_ADC 1024 /* One timetick as ADC count value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Persistence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define APDS990X_APERS_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define APDS990X_PPERS_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* Supported ID:s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define APDS990X_ID_0 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define APDS990X_ID_4 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define APDS990X_ID_29 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* pgain and pdiode settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define APDS_PGAIN_1X 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define APDS_PDIODE_IR 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define APDS990X_LUX_OUTPUT_SCALE 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Reverse chip factors for threshold calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct reverse_factors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u32 afactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int irf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) int cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int irf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct apds990x_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct apds990x_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct mutex mutex; /* avoid parallel access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct regulator_bulk_data regs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int prox_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) bool prox_continuous_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) bool lux_wait_fresh_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Chip parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct apds990x_chip_factors cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct reverse_factors rcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u16 atime; /* als integration time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u16 arate; /* als reporting rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u16 a_max_result; /* Max possible ADC value with current atime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) u8 again_meas; /* Gain used in last measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u8 again_next; /* Next calculated gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 pgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u8 pdiode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u8 pdrive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u8 lux_persistence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u8 prox_persistence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) u32 lux_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u32 lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u16 lux_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u16 lux_ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u16 lux_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 lux_thres_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u32 lux_thres_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u32 prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u16 prox_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u16 prox_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) char chipname[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u8 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define APDS_CALIB_SCALER 8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define APDS_LUX_NEUTRAL_CALIB_VALUE (1 * APDS_CALIB_SCALER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define APDS_PROX_NEUTRAL_CALIB_VALUE (1 * APDS_CALIB_SCALER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define APDS_PROX_DEF_THRES 600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define APDS_PROX_HYSTERESIS 50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define APDS_LUX_DEF_THRES_HI 101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define APDS_LUX_DEF_THRES_LO 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define APDS_DEFAULT_PROX_PERS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define APDS_TIMEOUT 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define APDS_STARTUP_DELAY 25000 /* us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define APDS_RANGE 65535
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define APDS_PROX_RANGE 1023
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define APDS_LUX_GAIN_LO_LIMIT 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define APDS_LUX_GAIN_LO_LIMIT_STRICT 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define TIMESTEP 87 /* 2.7ms is about 87 / 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define TIME_STEP_SCALER 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define APDS_LUX_AVERAGING_TIME 50 /* tolerates 50/60Hz ripple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define APDS_LUX_DEFAULT_RATE 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static const u8 again[] = {1, 8, 16, 120}; /* ALS gain steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Following two tables must match i.e 10Hz rate means 1 as persistence value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const u16 arates_hz[] = {10, 5, 2, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static const u8 apersis[] = {1, 2, 4, 5};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* Regulators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static const char reg_vcc[] = "Vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const char reg_vled[] = "Vled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static int apds990x_read_byte(struct apds990x_chip *chip, u8 reg, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *data = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int apds990x_read_word(struct apds990x_chip *chip, u8 reg, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = i2c_smbus_read_word_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) *data = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int apds990x_write_byte(struct apds990x_chip *chip, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = i2c_smbus_write_byte_data(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int apds990x_write_word(struct apds990x_chip *chip, u8 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) ret = i2c_smbus_write_word_data(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int apds990x_mode_on(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* ALS is mandatory, proximity optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u8 reg = APDS990X_EN_AIEN | APDS990X_EN_PON | APDS990X_EN_AEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) APDS990X_EN_WEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) reg |= APDS990X_EN_PIEN | APDS990X_EN_PEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return apds990x_write_byte(chip, APDS990X_ENABLE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static u16 apds990x_lux_to_threshold(struct apds990x_chip *chip, u32 lux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) u32 thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u32 cpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u32 ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (lux == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else if (lux == APDS_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return APDS_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * Reported LUX value is a combination of the IR and CLEAR channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * values. However, interrupt threshold is only for clear channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * This function approximates needed HW threshold value for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * LUX value in the current lightning type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * IR level compared to visible light varies heavily depending on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * source of the light
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * Calculate threshold value for the next measurement period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * Math: threshold = lux * cpl where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * cpl = atime * again / (glass_attenuation * device_factor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * (count-per-lux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * First remove calibration. Division by four is to avoid overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) lux = lux * (APDS_CALIB_SCALER / 4) / (chip->lux_calib / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Multiplication by 64 is to increase accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) cpl = ((u32)chip->atime * (u32)again[chip->again_next] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) APDS_PARAM_SCALE * 64) / (chip->cf.ga * chip->cf.df);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) thres = lux * cpl / 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Convert IR light from the latest result to match with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * new gain step. This helps to adapt with the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * source of light.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ir = (u32)chip->lux_ir * (u32)again[chip->again_next] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) (u32)again[chip->again_meas];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * Compensate count with IR light impact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * IAC1 > IAC2 (see apds990x_get_lux for formulas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (chip->lux_clear * APDS_PARAM_SCALE >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) chip->rcf.afactor * chip->lux_ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) thres = (chip->rcf.cf1 * thres + chip->rcf.irf1 * ir) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) thres = (chip->rcf.cf2 * thres + chip->rcf.irf2 * ir) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (thres >= chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) thres = chip->a_max_result - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static inline int apds990x_set_atime(struct apds990x_chip *chip, u32 time_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) u8 reg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) chip->atime = time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Formula is specified in the data sheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) reg_value = 256 - ((time_ms * TIME_STEP_SCALER) / TIMESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* Calculate max ADC value for given integration time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) chip->a_max_result = (u16)(256 - reg_value) * APDS990X_TIME_TO_ADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return apds990x_write_byte(chip, APDS990X_ATIME, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int apds990x_refresh_pthres(struct apds990x_chip *chip, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int ret, lo, hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (data < chip->prox_thres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) hi = chip->prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) lo = chip->prox_thres - APDS_PROX_HYSTERESIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (chip->prox_continuous_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) hi = chip->prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) hi = APDS_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ret = apds990x_write_word(chip, APDS990X_PILTL, lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ret |= apds990x_write_word(chip, APDS990X_PIHTL, hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) static int apds990x_refresh_athres(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = apds990x_write_word(chip, APDS990X_AILTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) apds990x_lux_to_threshold(chip, chip->lux_thres_lo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ret |= apds990x_write_word(chip, APDS990X_AIHTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) apds990x_lux_to_threshold(chip, chip->lux_thres_hi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static void apds990x_force_a_refresh(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* This will force ALS interrupt after the next measurement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) apds990x_write_word(chip, APDS990X_AILTL, APDS_LUX_DEF_THRES_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) apds990x_write_word(chip, APDS990X_AIHTL, APDS_LUX_DEF_THRES_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static void apds990x_force_p_refresh(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* This will force proximity interrupt after the next measurement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) apds990x_write_word(chip, APDS990X_PILTL, APDS_PROX_DEF_THRES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) apds990x_write_word(chip, APDS990X_PIHTL, APDS_PROX_DEF_THRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static int apds990x_calc_again(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) int curr_again = chip->again_meas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int next_again = chip->again_meas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Calculate suitable als gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (chip->lux_clear == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) next_again -= 2; /* ALS saturated. Decrease gain by 2 steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) else if (chip->lux_clear > chip->a_max_result / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) next_again--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) next_again += 2; /* Too dark. Increase gain by 2 steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) next_again++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /* Limit gain to available range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (next_again < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) next_again = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) else if (next_again > APDS990X_MAX_AGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) next_again = APDS990X_MAX_AGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Let's check can we trust the measured result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (chip->lux_clear == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Result can be totally garbage due to saturation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) else if (next_again != curr_again &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Gain is changed and measurement result is very small.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * Result can be totally garbage due to underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) chip->again_next = next_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) apds990x_write_byte(chip, APDS990X_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) (chip->pdrive << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) (chip->pdiode << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) (chip->pgain << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) (chip->again_next << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Error means bad result -> re-measurement is needed. The forced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * refresh uses fastest possible persistence setting to get result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * as soon as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) apds990x_force_a_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) apds990x_refresh_athres(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) static int apds990x_get_lux(struct apds990x_chip *chip, int clear, int ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int iac, iac1, iac2; /* IR adjusted counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) u32 lpc; /* Lux per count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* Formulas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * iac1 = CF1 * CLEAR_CH - IRF1 * IR_CH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * iac2 = CF2 * CLEAR_CH - IRF2 * IR_CH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) iac1 = (chip->cf.cf1 * clear - chip->cf.irf1 * ir) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) iac2 = (chip->cf.cf2 * clear - chip->cf.irf2 * ir) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) iac = max(iac1, iac2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) iac = max(iac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) lpc = APDS990X_LUX_OUTPUT_SCALE * (chip->cf.df * chip->cf.ga) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) (u32)(again[chip->again_meas] * (u32)chip->atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return (iac * lpc) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int apds990x_ack_int(struct apds990x_chip *chip, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u8 reg = APDS990x_CMD | APDS990x_CMD_TYPE_SPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) switch (mode & (APDS990X_ST_AINT | APDS990X_ST_PINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) case APDS990X_ST_AINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) reg |= APDS990X_INT_ACK_ALS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case APDS990X_ST_PINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) reg |= APDS990X_INT_ACK_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) reg |= APDS990X_INT_ACK_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) ret = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static irqreturn_t apds990x_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct apds990x_chip *chip = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) apds990x_read_byte(chip, APDS990X_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) apds990x_ack_int(chip, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (!pm_runtime_suspended(&chip->client->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (status & APDS990X_ST_AINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) apds990x_read_word(chip, APDS990X_CDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) &chip->lux_clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) apds990x_read_word(chip, APDS990X_IRDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) &chip->lux_ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Store used gain for calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) chip->again_meas = chip->again_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) chip->lux_raw = apds990x_get_lux(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) chip->lux_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) chip->lux_ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (apds990x_calc_again(chip) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* Result is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) chip->lux = chip->lux_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) chip->lux_wait_fresh_res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) wake_up(&chip->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) sysfs_notify(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) NULL, "lux0_input");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if ((status & APDS990X_ST_PINT) && chip->prox_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u16 clr_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) apds990x_read_word(chip, APDS990X_CDATAL, &clr_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * If ALS channel is saturated at min gain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * proximity gives false posivite values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * Just ignore them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (chip->again_meas == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) clr_ch == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) apds990x_read_word(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) APDS990X_PDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) &chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) apds990x_refresh_pthres(chip, chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (chip->prox_data < chip->prox_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) else if (!chip->prox_continuous_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) chip->prox_data = APDS_PROX_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) sysfs_notify(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) NULL, "prox0_raw");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int apds990x_configure(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* It is recommended to use disabled mode during these operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* conversion and wait times for different state machince states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) apds990x_write_byte(chip, APDS990X_PTIME, APDS990X_PTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) apds990x_write_byte(chip, APDS990X_WTIME, APDS990X_WTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) apds990x_set_atime(chip, APDS_LUX_AVERAGING_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) apds990x_write_byte(chip, APDS990X_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Persistence levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) apds990x_write_byte(chip, APDS990X_PERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) (chip->lux_persistence << APDS990X_APERS_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) (chip->prox_persistence << APDS990X_PPERS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) apds990x_write_byte(chip, APDS990X_PPCOUNT, chip->pdata->ppcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Start with relatively small gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) chip->again_meas = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) chip->again_next = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) apds990x_write_byte(chip, APDS990X_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) (chip->pdrive << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) (chip->pdiode << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) (chip->pgain << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) (chip->again_next << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int apds990x_detect(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) ret = apds990x_read_byte(chip, APDS990X_ID, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dev_err(&client->dev, "ID read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = apds990x_read_byte(chip, APDS990X_REV, &chip->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dev_err(&client->dev, "REV read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case APDS990X_ID_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case APDS990X_ID_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case APDS990X_ID_29:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) snprintf(chip->chipname, sizeof(chip->chipname), "APDS-990x");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int apds990x_chip_on(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int err = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Refresh all configs in case of regulators were off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) apds990x_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int apds990x_chip_off(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static ssize_t apds990x_lux_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) u32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) timeout = wait_event_interruptible_timeout(chip->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) !chip->lux_wait_fresh_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) msecs_to_jiffies(APDS_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) result = (chip->lux * chip->lux_calib) / APDS_CALIB_SCALER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (result > (APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) result = APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = sprintf(buf, "%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) result / APDS990X_LUX_OUTPUT_SCALE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) result % APDS990X_LUX_OUTPUT_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static DEVICE_ATTR(lux0_input, S_IRUGO, apds990x_lux_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static ssize_t apds990x_lux_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return sprintf(buf, "%u\n", APDS_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, apds990x_lux_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static ssize_t apds990x_lux_calib_format_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return sprintf(buf, "%u\n", APDS_CALIB_SCALER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) apds990x_lux_calib_format_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) static ssize_t apds990x_lux_calib_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return sprintf(buf, "%u\n", chip->lux_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static ssize_t apds990x_lux_calib_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) chip->lux_calib = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, apds990x_lux_calib_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) apds990x_lux_calib_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static ssize_t apds990x_rate_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) pos += sprintf(buf + pos, "%d ", arates_hz[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sprintf(buf + pos - 1, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static ssize_t apds990x_rate_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return sprintf(buf, "%d\n", chip->arate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int apds990x_set_arate(struct apds990x_chip *chip, int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (rate >= arates_hz[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (i == ARRAY_SIZE(arates_hz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Pick up corresponding persistence value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) chip->lux_persistence = apersis[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) chip->arate = arates_hz[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Persistence levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return apds990x_write_byte(chip, APDS990X_PERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) (chip->lux_persistence << APDS990X_APERS_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) (chip->prox_persistence << APDS990X_PPERS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static ssize_t apds990x_rate_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = apds990x_set_arate(chip, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static DEVICE_ATTR(lux0_rate_avail, S_IRUGO, apds990x_rate_avail, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, apds990x_rate_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) apds990x_rate_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static ssize_t apds990x_prox_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (pm_runtime_suspended(dev) || !chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = sprintf(buf, "%d\n", chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static DEVICE_ATTR(prox0_raw, S_IRUGO, apds990x_prox_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static ssize_t apds990x_prox_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return sprintf(buf, "%u\n", APDS_PROX_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static DEVICE_ATTR(prox0_sensor_range, S_IRUGO, apds990x_prox_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) static ssize_t apds990x_prox_enable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return sprintf(buf, "%d\n", chip->prox_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static ssize_t apds990x_prox_enable_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) chip->prox_en++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) else if (chip->prox_en > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) chip->prox_en--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, apds990x_prox_enable_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) apds990x_prox_enable_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) static const char *reporting_modes[] = {"trigger", "periodic"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static ssize_t apds990x_prox_reporting_mode_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) reporting_modes[!!chip->prox_continuous_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static ssize_t apds990x_prox_reporting_mode_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ret = sysfs_match_string(reporting_modes, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) chip->prox_continuous_mode = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static DEVICE_ATTR(prox0_reporting_mode, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) apds990x_prox_reporting_mode_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) apds990x_prox_reporting_mode_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) static ssize_t apds990x_prox_reporting_avail_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return sprintf(buf, "%s %s\n", reporting_modes[0], reporting_modes[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) static DEVICE_ATTR(prox0_reporting_mode_avail, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) apds990x_prox_reporting_avail_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static ssize_t apds990x_lux_thresh_above_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return sprintf(buf, "%d\n", chip->lux_thres_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static ssize_t apds990x_lux_thresh_below_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return sprintf(buf, "%d\n", chip->lux_thres_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) const char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) unsigned long thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) ret = kstrtoul(buf, 0, &thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (thresh > APDS_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) *target = thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * Don't update values in HW if we are still waiting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * first interrupt to come after device handle open call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!chip->lux_wait_fresh_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) apds990x_refresh_athres(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static ssize_t apds990x_lux_thresh_above_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_hi, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static ssize_t apds990x_lux_thresh_below_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_lo, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static DEVICE_ATTR(lux0_thresh_above_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) apds990x_lux_thresh_above_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) apds990x_lux_thresh_above_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static DEVICE_ATTR(lux0_thresh_below_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) apds990x_lux_thresh_below_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) apds990x_lux_thresh_below_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static ssize_t apds990x_prox_threshold_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return sprintf(buf, "%d\n", chip->prox_thres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static ssize_t apds990x_prox_threshold_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if ((value > APDS_RANGE) || (value == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) (value < APDS_PROX_HYSTERESIS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) chip->prox_thres = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) apds990x_force_p_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static DEVICE_ATTR(prox0_thresh_above_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) apds990x_prox_threshold_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) apds990x_prox_threshold_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static ssize_t apds990x_power_state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return sprintf(buf, "%d\n", !pm_runtime_suspended(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static ssize_t apds990x_power_state_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) chip->lux_wait_fresh_res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) apds990x_force_a_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) apds990x_force_p_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) apds990x_power_state_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) apds990x_power_state_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static ssize_t apds990x_chip_id_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return sprintf(buf, "%s %d\n", chip->chipname, chip->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static DEVICE_ATTR(chip_id, S_IRUGO, apds990x_chip_id_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static struct attribute *sysfs_attrs_ctrl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) &dev_attr_lux0_calibscale.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) &dev_attr_lux0_calibscale_default.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) &dev_attr_lux0_input.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) &dev_attr_lux0_sensor_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) &dev_attr_lux0_rate.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) &dev_attr_lux0_rate_avail.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) &dev_attr_lux0_thresh_above_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) &dev_attr_lux0_thresh_below_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) &dev_attr_prox0_raw_en.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) &dev_attr_prox0_raw.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) &dev_attr_prox0_sensor_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) &dev_attr_prox0_thresh_above_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) &dev_attr_prox0_reporting_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) &dev_attr_prox0_reporting_mode_avail.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) &dev_attr_chip_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) &dev_attr_power_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static const struct attribute_group apds990x_attribute_group[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {.attrs = sysfs_attrs_ctrl },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int apds990x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) struct apds990x_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) chip = kzalloc(sizeof *chip, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) chip->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) init_waitqueue_head(&chip->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) mutex_init(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) chip->pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (chip->pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) dev_err(&client->dev, "platform data is mandatory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) if (chip->pdata->cf.ga == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) /* set uncovered sensor default parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) chip->cf.ga = 1966; /* 0.48 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) chip->cf.cf1 = 4096; /* 1.00 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) chip->cf.irf1 = 9134; /* 2.23 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) chip->cf.cf2 = 2867; /* 0.70 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) chip->cf.irf2 = 5816; /* 1.42 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) chip->cf.df = 52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) chip->cf = chip->pdata->cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* precalculate inverse chip factors for threshold control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) chip->rcf.afactor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) (chip->cf.irf1 - chip->cf.irf2) * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) (chip->cf.cf1 - chip->cf.cf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) chip->rcf.cf1 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) chip->cf.cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) chip->rcf.irf1 = chip->cf.irf1 * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) chip->cf.cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) chip->rcf.cf2 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) chip->cf.cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) chip->rcf.irf2 = chip->cf.irf2 * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) chip->cf.cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* Set something to start with */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) chip->lux_thres_hi = APDS_LUX_DEF_THRES_HI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) chip->lux_thres_lo = APDS_LUX_DEF_THRES_LO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) chip->lux_calib = APDS_LUX_NEUTRAL_CALIB_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) chip->prox_thres = APDS_PROX_DEF_THRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) chip->pdrive = chip->pdata->pdrive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) chip->pdiode = APDS_PDIODE_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) chip->pgain = APDS_PGAIN_1X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) chip->prox_calib = APDS_PROX_NEUTRAL_CALIB_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) chip->prox_persistence = APDS_DEFAULT_PROX_PERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) chip->prox_continuous_mode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) chip->regs[0].supply = reg_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) chip->regs[1].supply = reg_vled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) err = regulator_bulk_get(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) dev_err(&client->dev, "Cannot get regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) dev_err(&client->dev, "Cannot enable regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) err = apds990x_detect(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) dev_err(&client->dev, "APDS990X not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) apds990x_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) apds990x_set_arate(chip, APDS_LUX_DEFAULT_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (chip->pdata->setup_resources) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) err = chip->pdata->setup_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) err = sysfs_create_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) apds990x_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev_err(&chip->client->dev, "Sysfs registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto fail4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) err = request_threaded_irq(client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) apds990x_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) "apds990x", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dev_err(&client->dev, "could not get IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) goto fail5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) fail5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) sysfs_remove_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) &apds990x_attribute_group[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) fail4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (chip->pdata && chip->pdata->release_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) chip->pdata->release_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) fail3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) fail2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fail1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static int apds990x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) free_irq(client->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) sysfs_remove_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) apds990x_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) if (chip->pdata && chip->pdata->release_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) chip->pdata->release_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (!pm_runtime_suspended(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static int apds990x_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int apds990x_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * If we were enabled at suspend time, it is expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * everything works nice and smoothly. Chip_on is enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) apds990x_chip_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int apds990x_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static int apds990x_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) apds990x_chip_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static const struct i2c_device_id apds990x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) {"apds990x", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) MODULE_DEVICE_TABLE(i2c, apds990x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static const struct dev_pm_ops apds990x_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) SET_SYSTEM_SLEEP_PM_OPS(apds990x_suspend, apds990x_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) SET_RUNTIME_PM_OPS(apds990x_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) apds990x_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static struct i2c_driver apds990x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .name = "apds990x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .pm = &apds990x_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .probe = apds990x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .remove = apds990x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .id_table = apds990x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) module_i2c_driver(apds990x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) MODULE_DESCRIPTION("APDS990X combined ALS and proximity sensor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) MODULE_LICENSE("GPL v2");