^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * isl29003.c - Linux kernel module for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Intersil ISL29003 ambient light sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * See file:Documentation/misc-devices/isl29003.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Based on code written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Rodolfo Giometti <giometti@linux.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Eurotech S.p.A. <info@eurotech.it>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define ISL29003_DRV_NAME "isl29003"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define DRIVER_VERSION "1.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define ISL29003_REG_COMMAND 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define ISL29003_ADC_ENABLED (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define ISL29003_ADC_PD (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define ISL29003_TIMING_INT (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define ISL29003_MODE_SHIFT (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ISL29003_RES_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define ISL29003_REG_CONTROL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define ISL29003_INT_FLG (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define ISL29003_RANGE_SHIFT (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define ISL29003_INT_PERSISTS_SHIFT (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define ISL29003_REG_IRQ_THRESH_HI 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define ISL29003_REG_IRQ_THRESH_LO 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define ISL29003_REG_LSB_SENSOR 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define ISL29003_REG_MSB_SENSOR 0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define ISL29003_REG_LSB_TIMER 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define ISL29003_REG_MSB_TIMER 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define ISL29003_NUM_CACHABLE_REGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct isl29003_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u8 power_state_before_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int gain_range[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 1000, 4000, 16000, 64000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * register access helpers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int __isl29003_read_reg(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u32 reg, u8 mask, u8 shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return (data->reg_cache[reg] & mask) >> shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int __isl29003_write_reg(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 reg, u8 mask, u8 shift, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (reg >= ISL29003_NUM_CACHABLE_REGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) tmp = data->reg_cache[reg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) tmp &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) tmp |= val << shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ret = i2c_smbus_write_byte_data(client, reg, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) data->reg_cache[reg] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * internally used functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int isl29003_get_range(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int isl29003_set_range(struct i2c_client *client, int range)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int isl29003_get_resolution(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ISL29003_RES_MASK, ISL29003_RES_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int isl29003_set_resolution(struct i2c_client *client, int res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int isl29003_get_mode(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ISL29003_RES_MASK, ISL29003_RES_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int isl29003_set_mode(struct i2c_client *client, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* power_state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int isl29003_set_power_state(struct i2c_client *client, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int isl29003_get_power_state(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return ~cmdreg & ISL29003_ADC_PD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int isl29003_get_adc_value(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int lsb, msb, range, bitdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (lsb < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return lsb;
^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) msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (msb < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return msb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) range = isl29003_get_range(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) bitdepth = (4 - isl29003_get_resolution(client)) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^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) * sysfs layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static ssize_t isl29003_show_range(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) return sprintf(buf, "%i\n", isl29003_get_range(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static ssize_t isl29003_store_range(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (val > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = isl29003_set_range(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) isl29003_show_range, isl29003_store_range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static ssize_t isl29003_show_resolution(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return sprintf(buf, "%d\n", isl29003_get_resolution(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static ssize_t isl29003_store_resolution(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (val > 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ret = isl29003_set_resolution(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) isl29003_show_resolution, isl29003_store_resolution);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static ssize_t isl29003_show_mode(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return sprintf(buf, "%d\n", isl29003_get_mode(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static ssize_t isl29003_store_mode(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (val > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = isl29003_set_mode(client, val);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) isl29003_show_mode, isl29003_store_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /* power state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static ssize_t isl29003_show_power_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return sprintf(buf, "%d\n", isl29003_get_power_state(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static ssize_t isl29003_store_power_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ret = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (val > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = isl29003_set_power_state(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) isl29003_show_power_state, isl29003_store_power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* lux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static ssize_t isl29003_show_lux(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* No LUX data if not operational */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!isl29003_get_power_state(client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static struct attribute *isl29003_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) &dev_attr_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) &dev_attr_resolution.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) &dev_attr_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) &dev_attr_power_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) &dev_attr_lux.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) NULL
^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) static const struct attribute_group isl29003_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .attrs = isl29003_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int isl29003_init_client(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* read all the registers once to fill the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * if one of the reads fails, we consider the init failed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int v = i2c_smbus_read_byte_data(client, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (v < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) data->reg_cache[i] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* set defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) isl29003_set_range(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) isl29003_set_resolution(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) isl29003_set_mode(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) isl29003_set_power_state(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) return 0;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * I2C layer
^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) static int isl29003_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct isl29003_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) i2c_set_clientdata(client, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* initialize the ISL29003 chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) err = isl29003_init_client(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) goto exit_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* register sysfs hooks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) goto exit_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) exit_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int isl29003_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) isl29003_set_power_state(client, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) kfree(i2c_get_clientdata(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int isl29003_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) data->power_state_before_suspend = isl29003_get_power_state(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) return isl29003_set_power_state(client, 0);
^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) static int isl29003_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct isl29003_data *data = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* restore registers from cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return isl29003_set_power_state(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) data->power_state_before_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static SIMPLE_DEV_PM_OPS(isl29003_pm_ops, isl29003_suspend, isl29003_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #define ISL29003_PM_OPS (&isl29003_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #define ISL29003_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static const struct i2c_device_id isl29003_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { "isl29003", 0 },
^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) MODULE_DEVICE_TABLE(i2c, isl29003_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static struct i2c_driver isl29003_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .name = ISL29003_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .pm = ISL29003_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .probe = isl29003_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .remove = isl29003_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .id_table = isl29003_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) module_i2c_driver(isl29003_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MODULE_VERSION(DRIVER_VERSION);