^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) * MAX44000 Ambient and Infrared Proximity Sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2016, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Data sheet: https://datasheets.maximintegrated.com/en/ds/MAX44000.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 7-bit I2C slave address 0x4a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^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/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/util_macros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MAX44000_DRV_NAME "max44000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* Registers in datasheet order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MAX44000_REG_STATUS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MAX44000_REG_CFG_MAIN 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MAX44000_REG_CFG_RX 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MAX44000_REG_CFG_TX 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX44000_REG_ALS_DATA_HI 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX44000_REG_ALS_DATA_LO 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MAX44000_REG_PRX_DATA 0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define MAX44000_REG_ALS_UPTHR_HI 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define MAX44000_REG_ALS_UPTHR_LO 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MAX44000_REG_ALS_LOTHR_HI 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define MAX44000_REG_ALS_LOTHR_LO 0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define MAX44000_REG_PST 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define MAX44000_REG_PRX_IND 0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define MAX44000_REG_PRX_THR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define MAX44000_REG_TRIM_GAIN_GREEN 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define MAX44000_REG_TRIM_GAIN_IR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* REG_CFG bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define MAX44000_CFG_ALSINTE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MAX44000_CFG_PRXINTE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define MAX44000_CFG_MASK 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define MAX44000_CFG_MODE_SHUTDOWN 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define MAX44000_CFG_MODE_ALS_GIR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MAX44000_CFG_MODE_ALS_G 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define MAX44000_CFG_MODE_ALS_IR 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define MAX44000_CFG_MODE_ALS_PRX 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define MAX44000_CFG_MODE_PRX 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define MAX44000_CFG_TRIM 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Upper 4 bits are not documented but start as 1 on powerup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Setting them to 0 causes proximity to misbehave so set them to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define MAX44000_REG_CFG_RX_DEFAULT 0xf0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* REG_RX bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MAX44000_CFG_RX_ALSTIM_MASK 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MAX44000_CFG_RX_ALSTIM_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define MAX44000_CFG_RX_ALSPGA_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define MAX44000_CFG_RX_ALSPGA_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* REG_TX bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define MAX44000_LED_CURRENT_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define MAX44000_LED_CURRENT_MAX 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define MAX44000_LED_CURRENT_DEFAULT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define MAX44000_ALSDATA_OVERFLOW 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct max44000_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Ensure naturally aligned timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u16 channels[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /* Default scale is set to the minimum of 0.03125 or 1 / (1 << 5) lux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define MAX44000_ALS_TO_LUX_DEFAULT_FRACTION_LOG2 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* Scale can be multiplied by up to 128x via ALSPGA for measurement gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const int max44000_alspga_shift[] = {0, 2, 4, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define MAX44000_ALSPGA_MAX_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Scale can be multiplied by up to 64x via ALSTIM because of lost resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * This scaling factor is hidden from userspace and instead accounted for when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * reading raw values from the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * This makes it possible to cleanly expose ALSPGA as IIO_CHAN_INFO_SCALE and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * ALSTIM as IIO_CHAN_INFO_INT_TIME without the values affecting each other.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Handling this internally is also required for buffer support because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * channel's scan_type can't be modified dynamically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define MAX44000_ALSTIM_SHIFT(alstim) (2 * (alstim))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Available integration times with pretty manual alignment: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const int max44000_int_time_avail_ns_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 100000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 25000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 6250000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 1562500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static const char max44000_int_time_avail_str[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "0.100 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) "0.025 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) "0.00625 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) "0.0015625";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Available scales (internal to ulux) with pretty manual alignment: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const int max44000_scale_avail_ulux_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 31250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static const char max44000_scale_avail_str[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "0.03125 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) "0.125 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) "0.5 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) "4";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define MAX44000_SCAN_INDEX_ALS 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define MAX44000_SCAN_INDEX_PRX 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static const struct iio_chan_spec max44000_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .type = IIO_LIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) BIT(IIO_CHAN_INFO_INT_TIME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .scan_index = MAX44000_SCAN_INDEX_ALS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .sign = 'u',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .realbits = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .type = IIO_PROXIMITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .scan_index = MAX44000_SCAN_INDEX_PRX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .sign = 'u',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .realbits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) IIO_CHAN_SOFT_TIMESTAMP(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .type = IIO_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .extend_name = "led",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .output = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .scan_index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int max44000_read_alstim(struct max44000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ret = regmap_read(data->regmap, MAX44000_REG_CFG_RX, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return (val & MAX44000_CFG_RX_ALSTIM_MASK) >> MAX44000_CFG_RX_ALSTIM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int max44000_write_alstim(struct max44000_data *data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return regmap_write_bits(data->regmap, MAX44000_REG_CFG_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) MAX44000_CFG_RX_ALSTIM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) val << MAX44000_CFG_RX_ALSTIM_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int max44000_read_alspga(struct max44000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ret = regmap_read(data->regmap, MAX44000_REG_CFG_RX, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return (val & MAX44000_CFG_RX_ALSPGA_MASK) >> MAX44000_CFG_RX_ALSPGA_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static int max44000_write_alspga(struct max44000_data *data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return regmap_write_bits(data->regmap, MAX44000_REG_CFG_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) MAX44000_CFG_RX_ALSPGA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) val << MAX44000_CFG_RX_ALSPGA_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int max44000_read_alsval(struct max44000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u16 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __be16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int alstim, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = regmap_bulk_read(data->regmap, MAX44000_REG_ALS_DATA_HI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) &val, sizeof(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) alstim = ret = max44000_read_alstim(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) regval = be16_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Overflow is explained on datasheet page 17.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * It's a warning that either the G or IR channel has become saturated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * and that the value in the register is likely incorrect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * The recommendation is to change the scale (ALSPGA).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * The driver just returns the max representable value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (regval & MAX44000_ALSDATA_OVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return 0x3FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return regval << MAX44000_ALSTIM_SHIFT(alstim);
^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 max44000_write_led_current_raw(struct max44000_data *data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Maybe we should clamp the value instead? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (val < 0 || val > MAX44000_LED_CURRENT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (val >= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) val += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return regmap_write_bits(data->regmap, MAX44000_REG_CFG_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) MAX44000_LED_CURRENT_MASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int max44000_read_led_current_raw(struct max44000_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = regmap_read(data->regmap, MAX44000_REG_CFG_TX, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) regval &= MAX44000_LED_CURRENT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (regval >= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) regval -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int max44000_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct max44000_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int alstim, alspga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case IIO_LIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = max44000_read_alsval(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) *val = regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case IIO_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = max44000_read_led_current_raw(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case IIO_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Output register is in 10s of miliamps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *val = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case IIO_LIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) alspga = ret = max44000_read_alspga(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* Avoid negative shifts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *val = (1 << MAX44000_ALSPGA_MAX_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *val2 = MAX44000_ALS_TO_LUX_DEFAULT_FRACTION_LOG2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) + MAX44000_ALSPGA_MAX_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) - max44000_alspga_shift[alspga];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return IIO_VAL_FRACTIONAL_LOG2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) case IIO_CHAN_INFO_INT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) alstim = ret = max44000_read_alstim(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) *val2 = max44000_int_time_avail_ns_array[alstim];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return IIO_VAL_INT_PLUS_NANO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int max44000_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct max44000_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (mask == IIO_CHAN_INFO_RAW && chan->type == IIO_CURRENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ret = max44000_write_led_current_raw(data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) } else if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) s64 valns = val * NSEC_PER_SEC + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int alstim = find_closest_descending(valns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) max44000_int_time_avail_ns_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ARRAY_SIZE(max44000_int_time_avail_ns_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = max44000_write_alstim(data, alstim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) } else if (mask == IIO_CHAN_INFO_SCALE && chan->type == IIO_LIGHT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) s64 valus = val * USEC_PER_SEC + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) int alspga = find_closest(valus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) max44000_scale_avail_ulux_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ARRAY_SIZE(max44000_scale_avail_ulux_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = max44000_write_alspga(data, alspga);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int max44000_write_raw_get_fmt(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return IIO_VAL_INT_PLUS_NANO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else if (mask == IIO_CHAN_INFO_SCALE && chan->type == IIO_LIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static IIO_CONST_ATTR(illuminance_integration_time_available, max44000_int_time_avail_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static IIO_CONST_ATTR(illuminance_scale_available, max44000_scale_avail_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static struct attribute *max44000_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) &iio_const_attr_illuminance_integration_time_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) &iio_const_attr_illuminance_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static const struct attribute_group max44000_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .attrs = max44000_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static const struct iio_info max44000_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .read_raw = max44000_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .write_raw = max44000_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .write_raw_get_fmt = max44000_write_raw_get_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .attrs = &max44000_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static bool max44000_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case MAX44000_REG_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case MAX44000_REG_CFG_MAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case MAX44000_REG_CFG_RX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case MAX44000_REG_CFG_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case MAX44000_REG_ALS_DATA_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) case MAX44000_REG_ALS_DATA_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) case MAX44000_REG_PRX_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case MAX44000_REG_ALS_UPTHR_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) case MAX44000_REG_ALS_UPTHR_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) case MAX44000_REG_ALS_LOTHR_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) case MAX44000_REG_ALS_LOTHR_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) case MAX44000_REG_PST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) case MAX44000_REG_PRX_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) case MAX44000_REG_PRX_THR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case MAX44000_REG_TRIM_GAIN_GREEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case MAX44000_REG_TRIM_GAIN_IR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static bool max44000_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) case MAX44000_REG_CFG_MAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) case MAX44000_REG_CFG_RX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) case MAX44000_REG_CFG_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) case MAX44000_REG_ALS_UPTHR_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) case MAX44000_REG_ALS_UPTHR_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) case MAX44000_REG_ALS_LOTHR_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) case MAX44000_REG_ALS_LOTHR_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case MAX44000_REG_PST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case MAX44000_REG_PRX_IND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case MAX44000_REG_PRX_THR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case MAX44000_REG_TRIM_GAIN_GREEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case MAX44000_REG_TRIM_GAIN_IR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static bool max44000_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case MAX44000_REG_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case MAX44000_REG_ALS_DATA_HI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case MAX44000_REG_ALS_DATA_LO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case MAX44000_REG_PRX_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return false;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static bool max44000_precious_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return reg == MAX44000_REG_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static const struct regmap_config max44000_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .max_register = MAX44000_REG_PRX_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .readable_reg = max44000_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .writeable_reg = max44000_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .volatile_reg = max44000_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .precious_reg = max44000_precious_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .use_single_read = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .use_single_write = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static irqreturn_t max44000_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct max44000_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (test_bit(MAX44000_SCAN_INDEX_ALS, indio_dev->active_scan_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = max44000_read_alsval(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) data->scan.channels[index++] = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (test_bit(MAX44000_SCAN_INDEX_PRX, indio_dev->active_scan_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = regmap_read(data->regmap, MAX44000_REG_PRX_DATA, ®val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) data->scan.channels[index] = regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int max44000_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) struct max44000_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) int ret, reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) data->regmap = devm_regmap_init_i2c(client, &max44000_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (IS_ERR(data->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_err(&client->dev, "regmap_init failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return PTR_ERR(data->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) indio_dev->info = &max44000_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) indio_dev->name = MAX44000_DRV_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) indio_dev->channels = max44000_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) indio_dev->num_channels = ARRAY_SIZE(max44000_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * The device doesn't have a reset function so we just clear some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * important bits at probe time to ensure sane operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * Since we don't support interrupts/events the threshold values are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * not important. We also don't touch trim values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Reset ALS scaling bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) ret = regmap_write(data->regmap, MAX44000_REG_CFG_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) MAX44000_REG_CFG_RX_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev_err(&client->dev, "failed to write default CFG_RX: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * By default the LED pulse used for the proximity sensor is disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * Set a middle value so that we get some sort of valid data by default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ret = max44000_write_led_current_raw(data, MAX44000_LED_CURRENT_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dev_err(&client->dev, "failed to write init config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /* Reset CFG bits to ALS_PRX mode which allows easy reading of both values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) reg = MAX44000_CFG_TRIM | MAX44000_CFG_MODE_ALS_PRX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ret = regmap_write(data->regmap, MAX44000_REG_CFG_MAIN, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) dev_err(&client->dev, "failed to write init config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /* Read status at least once to clear any stale interrupt bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ret = regmap_read(data->regmap, MAX44000_REG_STATUS, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dev_err(&client->dev, "failed to read init status: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = iio_triggered_buffer_setup(indio_dev, NULL, max44000_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) dev_err(&client->dev, "iio triggered buffer setup failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int max44000_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static const struct i2c_device_id max44000_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {"max44000", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) MODULE_DEVICE_TABLE(i2c, max44000_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static const struct acpi_device_id max44000_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {"MAX44000", 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) MODULE_DEVICE_TABLE(acpi, max44000_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static struct i2c_driver max44000_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .name = MAX44000_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .acpi_match_table = ACPI_PTR(max44000_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) .probe = max44000_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) .remove = max44000_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) .id_table = max44000_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) module_i2c_driver(max44000_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) MODULE_AUTHOR("Crestez Dan Leonard <leonard.crestez@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) MODULE_DESCRIPTION("MAX44000 Ambient and Infrared Proximity Sensor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) MODULE_LICENSE("GPL v2");