Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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, &regval);
^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, &regval);
^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, &regval);
^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, &reg);
^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");