^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) * drivers/iio/light/tsl2563.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2008 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Written by Timo O. Karjalainen <timo.o.karjalainen@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Contact: Amit Kucheria <amit.kucheria@verdurent.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Converted to IIO driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Amit Kucheria <amit.kucheria@verdurent.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/platform_data/tsl2563.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Use this many bits for fraction part. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ADC_FRAC_BITS 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* Given number of 1/10000's in ADC_FRAC_BITS precision. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define FRAC10K(f) (((f) * (1L << (ADC_FRAC_BITS))) / (10000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Bits used for fraction in calibration coefficients.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define CALIB_FRAC_BITS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* 0.5 in CALIB_FRAC_BITS precision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CALIB_FRAC_HALF (1 << (CALIB_FRAC_BITS - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* Make a fraction from a number n that was multiplied with b. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CALIB_FRAC(n, b) (((n) << CALIB_FRAC_BITS) / (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Decimal 10^(digits in sysfs presentation) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CALIB_BASE_SYSFS 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define TSL2563_CMD 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TSL2563_CLEARINT 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TSL2563_REG_CTRL 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define TSL2563_REG_TIMING 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TSL2563_REG_LOWLOW 0x02 /* data0 low threshold, 2 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TSL2563_REG_LOWHIGH 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TSL2563_REG_HIGHLOW 0x04 /* data0 high threshold, 2 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define TSL2563_REG_HIGHHIGH 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define TSL2563_REG_INT 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define TSL2563_REG_ID 0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TSL2563_REG_DATA0LOW 0x0c /* broadband sensor value, 2 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TSL2563_REG_DATA0HIGH 0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TSL2563_REG_DATA1LOW 0x0e /* infrared sensor value, 2 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TSL2563_REG_DATA1HIGH 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define TSL2563_CMD_POWER_ON 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TSL2563_CMD_POWER_OFF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define TSL2563_CTRL_POWER_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define TSL2563_TIMING_13MS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define TSL2563_TIMING_100MS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define TSL2563_TIMING_400MS 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define TSL2563_TIMING_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define TSL2563_TIMING_GAIN16 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define TSL2563_TIMING_GAIN1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TSL2563_INT_DISABLED 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define TSL2563_INT_LEVEL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define TSL2563_INT_PERSIST(n) ((n) & 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct tsl2563_gainlevel_coeff {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u8 gaintime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u16 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static const struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .min = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .max = 65534,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .gaintime = TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .min = 2048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .max = 65534,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .gaintime = TSL2563_TIMING_100MS | TSL2563_TIMING_GAIN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .min = 4095,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .max = 37177,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .gaintime = TSL2563_TIMING_13MS | TSL2563_TIMING_GAIN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .min = 3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .max = 65535,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct tsl2563_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct delayed_work poweroff_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Remember state for suspend and resume functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) bool suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct tsl2563_gainlevel_coeff const *gainlevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u16 low_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u16 high_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) bool int_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Calibration coefficients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u32 calib0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u32 calib1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int cover_comp_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Cache current values, to be returned while suspended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 data0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u32 data1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int tsl2563_set_power(struct tsl2563_chip *chip, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) cmd = on ? TSL2563_CMD_POWER_ON : TSL2563_CMD_POWER_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) TSL2563_CMD | TSL2563_REG_CTRL, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Return value is 0 for off, 1 for on, or a negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * code if reading failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int tsl2563_get_power(struct tsl2563_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return (ret & TSL2563_CTRL_POWER_MASK) == TSL2563_CMD_POWER_ON;
^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) static int tsl2563_configure(struct tsl2563_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) TSL2563_CMD | TSL2563_REG_TIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) chip->gainlevel->gaintime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) TSL2563_CMD | TSL2563_REG_HIGHLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) chip->high_thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) TSL2563_CMD | TSL2563_REG_HIGHHIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) (chip->high_thres >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) TSL2563_CMD | TSL2563_REG_LOWLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) chip->low_thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) TSL2563_CMD | TSL2563_REG_LOWHIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (chip->low_thres >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Interrupt register is automatically written anyway if it is relevant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * so is not here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void tsl2563_poweroff_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct tsl2563_chip *chip =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) container_of(work, struct tsl2563_chip, poweroff_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) tsl2563_set_power(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int tsl2563_detect(struct tsl2563_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = tsl2563_set_power(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ret = tsl2563_get_power(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return ret ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int tsl2563_read_id(struct tsl2563_chip *chip, u8 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = i2c_smbus_read_byte_data(client, TSL2563_CMD | TSL2563_REG_ID);
^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) *id = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return 0;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * "Normalized" ADC value is one obtained with 400ms of integration time and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * 16x gain. This function returns the number of bits of shift needed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * convert between normalized values and HW values obtained using given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * timing and gain settings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int tsl2563_adc_shiftbits(u8 timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) switch (timing & TSL2563_TIMING_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case TSL2563_TIMING_13MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) shift += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) case TSL2563_TIMING_100MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) shift += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case TSL2563_TIMING_400MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* no-op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (!(timing & TSL2563_TIMING_GAIN16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) shift += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Convert a HW ADC value to normalized scale. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static u32 tsl2563_normalize_adc(u16 adc, u8 timing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return adc << tsl2563_adc_shiftbits(timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void tsl2563_wait_adc(struct tsl2563_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) unsigned int delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) switch (chip->gainlevel->gaintime & TSL2563_TIMING_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case TSL2563_TIMING_13MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) delay = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case TSL2563_TIMING_100MS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) delay = 101;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) delay = 402;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * TODO: Make sure that we wait at least required delay but why we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * have to extend it one tick more?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) schedule_timeout_interruptible(msecs_to_jiffies(delay) + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static int tsl2563_adjust_gainlevel(struct tsl2563_chip *chip, u16 adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (adc > chip->gainlevel->max || adc < chip->gainlevel->min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (adc > chip->gainlevel->max) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) chip->gainlevel++ : chip->gainlevel--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) TSL2563_CMD | TSL2563_REG_TIMING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) chip->gainlevel->gaintime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) tsl2563_wait_adc(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) tsl2563_wait_adc(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int tsl2563_get_adc(struct tsl2563_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u16 adc0, adc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int retry = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (chip->suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (!chip->int_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) cancel_delayed_work(&chip->poweroff_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!tsl2563_get_power(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) ret = tsl2563_set_power(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ret = tsl2563_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tsl2563_wait_adc(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) while (retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = i2c_smbus_read_word_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) TSL2563_CMD | TSL2563_REG_DATA0LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) adc0 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = i2c_smbus_read_word_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) TSL2563_CMD | TSL2563_REG_DATA1LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) adc1 = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) retry = tsl2563_adjust_gainlevel(chip, adc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) chip->data0 = tsl2563_normalize_adc(adc0, chip->gainlevel->gaintime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) chip->data1 = tsl2563_normalize_adc(adc1, chip->gainlevel->gaintime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!chip->int_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static inline int tsl2563_calib_to_sysfs(u32 calib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return (int) (((calib * CALIB_BASE_SYSFS) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) CALIB_FRAC_HALF) >> CALIB_FRAC_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static inline u32 tsl2563_calib_from_sysfs(int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return (((u32) value) << CALIB_FRAC_BITS) / CALIB_BASE_SYSFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * Conversions between lux and ADC values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * The basic formula is lux = c0 * adc0 - c1 * adc1, where c0 and c1 are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * appropriate constants. Different constants are needed for different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * kinds of light, determined by the ratio adc1/adc0 (basically the ratio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * of the intensities in infrared and visible wavelengths). lux_table below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * lists the upper threshold of the adc1/adc0 ratio and the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * constants.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct tsl2563_lux_coeff {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) unsigned long ch_ratio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) unsigned long ch0_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) unsigned long ch1_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static const struct tsl2563_lux_coeff lux_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) .ch_ratio = FRAC10K(1300),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .ch0_coeff = FRAC10K(315),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .ch1_coeff = FRAC10K(262),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) .ch_ratio = FRAC10K(2600),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .ch0_coeff = FRAC10K(337),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .ch1_coeff = FRAC10K(430),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) .ch_ratio = FRAC10K(3900),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .ch0_coeff = FRAC10K(363),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .ch1_coeff = FRAC10K(529),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .ch_ratio = FRAC10K(5200),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .ch0_coeff = FRAC10K(392),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .ch1_coeff = FRAC10K(605),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .ch_ratio = FRAC10K(6500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .ch0_coeff = FRAC10K(229),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .ch1_coeff = FRAC10K(291),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .ch_ratio = FRAC10K(8000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) .ch0_coeff = FRAC10K(157),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) .ch1_coeff = FRAC10K(180),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) .ch_ratio = FRAC10K(13000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) .ch0_coeff = FRAC10K(34),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .ch1_coeff = FRAC10K(26),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .ch_ratio = ULONG_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) .ch0_coeff = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .ch1_coeff = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Convert normalized, scaled ADC values to lux. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static unsigned int tsl2563_adc_to_lux(u32 adc0, u32 adc1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) const struct tsl2563_lux_coeff *lp = lux_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unsigned long ratio, lux, ch0 = adc0, ch1 = adc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) ratio = ch0 ? ((ch1 << ADC_FRAC_BITS) / ch0) : ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) while (lp->ch_ratio < ratio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) lp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) lux = ch0 * lp->ch0_coeff - ch1 * lp->ch1_coeff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return (unsigned int) (lux >> ADC_FRAC_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Apply calibration coefficient to ADC count. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static u32 tsl2563_calib_adc(u32 adc, u32 calib)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) unsigned long scaled = adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) scaled *= calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) scaled >>= CALIB_FRAC_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return (u32) scaled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int tsl2563_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) int val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (mask != IIO_CHAN_INFO_CALIBSCALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (chan->channel2 == IIO_MOD_LIGHT_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) chip->calib0 = tsl2563_calib_from_sysfs(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) else if (chan->channel2 == IIO_MOD_LIGHT_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) chip->calib1 = tsl2563_calib_from_sysfs(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int tsl2563_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int *val2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) u32 calib0, calib1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case IIO_LIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) ret = tsl2563_get_adc(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) calib0 = tsl2563_calib_adc(chip->data0, chip->calib0) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) chip->cover_comp_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) calib1 = tsl2563_calib_adc(chip->data1, chip->calib1) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) chip->cover_comp_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) *val = tsl2563_adc_to_lux(calib0, calib1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = tsl2563_get_adc(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (chan->channel2 == IIO_MOD_LIGHT_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *val = chip->data0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) *val = chip->data1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case IIO_CHAN_INFO_CALIBSCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (chan->channel2 == IIO_MOD_LIGHT_BOTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) *val = tsl2563_calib_to_sysfs(chip->calib0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) *val = tsl2563_calib_to_sysfs(chip->calib1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static const struct iio_event_spec tsl2563_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) .type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) .dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .mask_separate = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) .type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) .dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) .mask_separate = BIT(IIO_EV_INFO_VALUE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static const struct iio_chan_spec tsl2563_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .type = IIO_LIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .indexed = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .channel = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .type = IIO_INTENSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .modified = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .channel2 = IIO_MOD_LIGHT_BOTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) BIT(IIO_CHAN_INFO_CALIBSCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .event_spec = tsl2563_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .num_event_specs = ARRAY_SIZE(tsl2563_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .type = IIO_INTENSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .modified = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .channel2 = IIO_MOD_LIGHT_IR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) BIT(IIO_CHAN_INFO_CALIBSCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int tsl2563_read_thresh(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) const struct iio_chan_spec *chan, enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) enum iio_event_direction dir, enum iio_event_info info, int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *val = chip->high_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) *val = chip->low_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return IIO_VAL_INT;
^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) static int tsl2563_write_thresh(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) const struct iio_chan_spec *chan, enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) enum iio_event_direction dir, enum iio_event_info info, int val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) u8 address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (dir == IIO_EV_DIR_RISING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) address = TSL2563_REG_HIGHLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) address = TSL2563_REG_LOWLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) val & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) TSL2563_CMD | (address + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) (val >> 8) & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (dir == IIO_EV_DIR_RISING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) chip->high_thres = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) chip->low_thres = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static irqreturn_t tsl2563_event_handler(int irq, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct iio_dev *dev_info = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct tsl2563_chip *chip = iio_priv(dev_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) iio_push_event(dev_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) IIO_EV_DIR_EITHER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) iio_get_time_ns(dev_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* clear the interrupt and push the event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) i2c_smbus_write_byte(chip->client, TSL2563_CMD | TSL2563_CLEARINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) const struct iio_chan_spec *chan, enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) enum iio_event_direction dir, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (state && !(chip->intr & 0x30)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) chip->intr &= ~0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) chip->intr |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* ensure the chip is actually on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) cancel_delayed_work(&chip->poweroff_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!tsl2563_get_power(chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = tsl2563_set_power(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = tsl2563_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) TSL2563_CMD | TSL2563_REG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) chip->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) chip->int_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (!state && (chip->intr & 0x30)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) chip->intr &= ~0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ret = i2c_smbus_write_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) TSL2563_CMD | TSL2563_REG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) chip->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) chip->int_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /* now the interrupt is not enabled, we can go to sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) const struct iio_chan_spec *chan, enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ret = i2c_smbus_read_byte_data(chip->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) TSL2563_CMD | TSL2563_REG_INT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return !!(ret & 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static const struct iio_info tsl2563_info_no_irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) .read_raw = &tsl2563_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) .write_raw = &tsl2563_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static const struct iio_info tsl2563_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) .read_raw = &tsl2563_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) .write_raw = &tsl2563_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) .read_event_value = &tsl2563_read_thresh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) .write_event_value = &tsl2563_write_thresh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) .read_event_config = &tsl2563_read_interrupt_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) .write_event_config = &tsl2563_write_interrupt_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static int tsl2563_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) const struct i2c_device_id *device_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct tsl2563_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct tsl2563_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct device_node *np = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) u8 id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) chip->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) err = tsl2563_detect(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_err(&client->dev, "detect error %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) err = tsl2563_read_id(chip, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(&client->dev, "read id error %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) mutex_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Default values used until userspace says otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) chip->low_thres = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) chip->high_thres = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) chip->gainlevel = tsl2563_gainlevel_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) chip->intr = TSL2563_INT_PERSIST(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) chip->calib0 = tsl2563_calib_from_sysfs(CALIB_BASE_SYSFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) chip->calib1 = tsl2563_calib_from_sysfs(CALIB_BASE_SYSFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) chip->cover_comp_gain = pdata->cover_comp_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) else if (np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) of_property_read_u32(np, "amstaos,cover-comp-gain",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) &chip->cover_comp_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) chip->cover_comp_gain = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) indio_dev->name = client->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) indio_dev->channels = tsl2563_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) indio_dev->info = &tsl2563_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) indio_dev->info = &tsl2563_info_no_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) err = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) &tsl2563_event_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) IRQF_TRIGGER_RISING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) "tsl2563_event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) dev_err(&client->dev, "irq request error %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) err = tsl2563_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) dev_err(&client->dev, "configure error %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) INIT_DELAYED_WORK(&chip->poweroff_work, tsl2563_poweroff_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* The interrupt cannot yet be enabled so this is fine without lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) err = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(&client->dev, "iio registration error %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) cancel_delayed_work_sync(&chip->poweroff_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) static int tsl2563_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (!chip->int_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) cancel_delayed_work(&chip->poweroff_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* Ensure that interrupts are disabled - then flush any bottom halves */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) chip->intr &= ~0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) i2c_smbus_write_byte_data(chip->client, TSL2563_CMD | TSL2563_REG_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) chip->intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) flush_scheduled_work();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) tsl2563_set_power(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int tsl2563_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = tsl2563_set_power(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) chip->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static int tsl2563_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) struct tsl2563_chip *chip = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) mutex_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ret = tsl2563_set_power(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ret = tsl2563_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) chip->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) mutex_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static SIMPLE_DEV_PM_OPS(tsl2563_pm_ops, tsl2563_suspend, tsl2563_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) #define TSL2563_PM_OPS (&tsl2563_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) #define TSL2563_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static const struct i2c_device_id tsl2563_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) { "tsl2560", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) { "tsl2561", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) { "tsl2562", 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) { "tsl2563", 3 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) MODULE_DEVICE_TABLE(i2c, tsl2563_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static const struct of_device_id tsl2563_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) { .compatible = "amstaos,tsl2560" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) { .compatible = "amstaos,tsl2561" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) { .compatible = "amstaos,tsl2562" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) { .compatible = "amstaos,tsl2563" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) MODULE_DEVICE_TABLE(of, tsl2563_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) static struct i2c_driver tsl2563_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .name = "tsl2563",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .of_match_table = tsl2563_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .pm = TSL2563_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) .probe = tsl2563_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .remove = tsl2563_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .id_table = tsl2563_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) module_i2c_driver(tsl2563_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) MODULE_AUTHOR("Nokia Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) MODULE_DESCRIPTION("tsl2563 light sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) MODULE_LICENSE("GPL");