0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/bits.h>
0018 #include <linux/i2c.h>
0019 #include <linux/iio/events.h>
0020 #include <linux/iio/iio.h>
0021 #include <linux/iio/sysfs.h>
0022 #include <linux/interrupt.h>
0023 #include <linux/module.h>
0024 #include <linux/util_macros.h>
0025
0026 #define MAX44009_DRV_NAME "max44009"
0027
0028
0029 #define MAX44009_REG_INT_STATUS 0x0
0030 #define MAX44009_REG_INT_EN 0x1
0031 #define MAX44009_REG_CFG 0x2
0032 #define MAX44009_REG_LUX_HI 0x3
0033 #define MAX44009_REG_LUX_LO 0x4
0034 #define MAX44009_REG_UPPER_THR 0x5
0035 #define MAX44009_REG_LOWER_THR 0x6
0036 #define MAX44009_REG_THR_TIMER 0x7
0037
0038 #define MAX44009_CFG_TIM_MASK GENMASK(2, 0)
0039 #define MAX44009_CFG_MAN_MODE_MASK BIT(6)
0040
0041
0042 #define MAX44009_MAXIMUM_THRESHOLD 7520256
0043
0044 #define MAX44009_THRESH_EXP_MASK (0xf << 4)
0045 #define MAX44009_THRESH_EXP_RSHIFT 4
0046 #define MAX44009_THRESH_MANT_LSHIFT 4
0047 #define MAX44009_THRESH_MANT_MASK 0xf
0048
0049 #define MAX44009_UPPER_THR_MINIMUM 15
0050
0051
0052 #define MAX44009_SCALE_NUMERATOR 45
0053 #define MAX44009_SCALE_DENOMINATOR 1000
0054
0055
0056 #define MAX44009_FRACT_MULT 1000000
0057
0058 static const u32 max44009_int_time_ns_array[] = {
0059 800000000,
0060 400000000,
0061 200000000,
0062 100000000,
0063 50000000,
0064 25000000,
0065 12500000,
0066 6250000,
0067 };
0068
0069 static const char max44009_int_time_str[] =
0070 "0.8 "
0071 "0.4 "
0072 "0.2 "
0073 "0.1 "
0074 "0.05 "
0075 "0.025 "
0076 "0.0125 "
0077 "0.00625";
0078
0079 struct max44009_data {
0080 struct i2c_client *client;
0081 struct mutex lock;
0082 };
0083
0084 static const struct iio_event_spec max44009_event_spec[] = {
0085 {
0086 .type = IIO_EV_TYPE_THRESH,
0087 .dir = IIO_EV_DIR_RISING,
0088 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0089 BIT(IIO_EV_INFO_ENABLE),
0090 },
0091 {
0092 .type = IIO_EV_TYPE_THRESH,
0093 .dir = IIO_EV_DIR_FALLING,
0094 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0095 BIT(IIO_EV_INFO_ENABLE),
0096 },
0097 };
0098
0099 static const struct iio_chan_spec max44009_channels[] = {
0100 {
0101 .type = IIO_LIGHT,
0102 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
0103 BIT(IIO_CHAN_INFO_INT_TIME),
0104 .event_spec = max44009_event_spec,
0105 .num_event_specs = ARRAY_SIZE(max44009_event_spec),
0106 },
0107 };
0108
0109 static int max44009_read_int_time(struct max44009_data *data)
0110 {
0111
0112 int ret = i2c_smbus_read_byte_data(data->client, MAX44009_REG_CFG);
0113
0114 if (ret < 0)
0115 return ret;
0116
0117 return max44009_int_time_ns_array[ret & MAX44009_CFG_TIM_MASK];
0118 }
0119
0120 static int max44009_write_int_time(struct max44009_data *data,
0121 int val, int val2)
0122 {
0123 struct i2c_client *client = data->client;
0124 int ret, int_time, config;
0125 s64 ns;
0126
0127 ns = val * NSEC_PER_SEC + val2;
0128 int_time = find_closest_descending(
0129 ns,
0130 max44009_int_time_ns_array,
0131 ARRAY_SIZE(max44009_int_time_ns_array));
0132
0133 ret = i2c_smbus_read_byte_data(client, MAX44009_REG_CFG);
0134 if (ret < 0)
0135 return ret;
0136
0137 config = ret;
0138 config &= int_time;
0139
0140
0141
0142
0143
0144 config |= MAX44009_CFG_MAN_MODE_MASK;
0145
0146 return i2c_smbus_write_byte_data(client, MAX44009_REG_CFG, config);
0147 }
0148
0149 static int max44009_write_raw(struct iio_dev *indio_dev,
0150 struct iio_chan_spec const *chan, int val,
0151 int val2, long mask)
0152 {
0153 struct max44009_data *data = iio_priv(indio_dev);
0154 int ret;
0155
0156 if (mask == IIO_CHAN_INFO_INT_TIME && chan->type == IIO_LIGHT) {
0157 mutex_lock(&data->lock);
0158 ret = max44009_write_int_time(data, val, val2);
0159 mutex_unlock(&data->lock);
0160 return ret;
0161 }
0162 return -EINVAL;
0163 }
0164
0165 static int max44009_write_raw_get_fmt(struct iio_dev *indio_dev,
0166 struct iio_chan_spec const *chan,
0167 long mask)
0168 {
0169 return IIO_VAL_INT_PLUS_NANO;
0170 }
0171
0172 static int max44009_lux_raw(u8 hi, u8 lo)
0173 {
0174 int mantissa;
0175 int exponent;
0176
0177
0178
0179
0180
0181 mantissa = ((hi & 0xf) << 4) | (lo & 0xf);
0182
0183
0184 exponent = (hi >> 4) & 0xf;
0185
0186
0187
0188
0189 exponent = 1 << exponent;
0190
0191 return exponent * mantissa;
0192 }
0193
0194 #define MAX44009_READ_LUX_XFER_LEN (4)
0195
0196 static int max44009_read_lux_raw(struct max44009_data *data)
0197 {
0198 int ret;
0199 u8 hireg = MAX44009_REG_LUX_HI;
0200 u8 loreg = MAX44009_REG_LUX_LO;
0201 u8 lo = 0;
0202 u8 hi = 0;
0203
0204 struct i2c_msg msgs[] = {
0205 {
0206 .addr = data->client->addr,
0207 .flags = 0,
0208 .len = sizeof(hireg),
0209 .buf = &hireg,
0210 },
0211 {
0212 .addr = data->client->addr,
0213 .flags = I2C_M_RD,
0214 .len = sizeof(hi),
0215 .buf = &hi,
0216 },
0217 {
0218 .addr = data->client->addr,
0219 .flags = 0,
0220 .len = sizeof(loreg),
0221 .buf = &loreg,
0222 },
0223 {
0224 .addr = data->client->addr,
0225 .flags = I2C_M_RD,
0226 .len = sizeof(lo),
0227 .buf = &lo,
0228 }
0229 };
0230
0231
0232
0233
0234
0235
0236
0237 ret = i2c_transfer(data->client->adapter,
0238 msgs, MAX44009_READ_LUX_XFER_LEN);
0239
0240 if (ret != MAX44009_READ_LUX_XFER_LEN)
0241 return -EIO;
0242
0243 return max44009_lux_raw(hi, lo);
0244 }
0245
0246 static int max44009_read_raw(struct iio_dev *indio_dev,
0247 struct iio_chan_spec const *chan, int *val,
0248 int *val2, long mask)
0249 {
0250 struct max44009_data *data = iio_priv(indio_dev);
0251 int lux_raw;
0252 int ret;
0253
0254 switch (mask) {
0255 case IIO_CHAN_INFO_PROCESSED:
0256 switch (chan->type) {
0257 case IIO_LIGHT:
0258 ret = max44009_read_lux_raw(data);
0259 if (ret < 0)
0260 return ret;
0261 lux_raw = ret;
0262
0263 *val = lux_raw * MAX44009_SCALE_NUMERATOR;
0264 *val2 = MAX44009_SCALE_DENOMINATOR;
0265 return IIO_VAL_FRACTIONAL;
0266 default:
0267 return -EINVAL;
0268 }
0269 case IIO_CHAN_INFO_INT_TIME:
0270 switch (chan->type) {
0271 case IIO_LIGHT:
0272 ret = max44009_read_int_time(data);
0273 if (ret < 0)
0274 return ret;
0275
0276 *val2 = ret;
0277 *val = 0;
0278 return IIO_VAL_INT_PLUS_NANO;
0279 default:
0280 return -EINVAL;
0281 }
0282 default:
0283 return -EINVAL;
0284 }
0285 }
0286
0287 static IIO_CONST_ATTR(illuminance_integration_time_available,
0288 max44009_int_time_str);
0289
0290 static struct attribute *max44009_attributes[] = {
0291 &iio_const_attr_illuminance_integration_time_available.dev_attr.attr,
0292 NULL,
0293 };
0294
0295 static const struct attribute_group max44009_attribute_group = {
0296 .attrs = max44009_attributes,
0297 };
0298
0299 static int max44009_threshold_byte_from_fraction(int integral, int fractional)
0300 {
0301 int mantissa, exp;
0302
0303 if ((integral <= 0 && fractional <= 0) ||
0304 integral > MAX44009_MAXIMUM_THRESHOLD ||
0305 (integral == MAX44009_MAXIMUM_THRESHOLD && fractional != 0))
0306 return -EINVAL;
0307
0308
0309 mantissa = integral * MAX44009_SCALE_DENOMINATOR;
0310 mantissa /= MAX44009_SCALE_NUMERATOR;
0311
0312
0313 mantissa += fractional / MAX44009_FRACT_MULT *
0314 (MAX44009_SCALE_DENOMINATOR / MAX44009_SCALE_NUMERATOR);
0315
0316 for (exp = 0; mantissa > 0xff; exp++)
0317 mantissa >>= 1;
0318
0319 mantissa >>= 4;
0320 mantissa &= 0xf;
0321 exp <<= 4;
0322
0323 return exp | mantissa;
0324 }
0325
0326 static int max44009_get_thr_reg(enum iio_event_direction dir)
0327 {
0328 switch (dir) {
0329 case IIO_EV_DIR_RISING:
0330 return MAX44009_REG_UPPER_THR;
0331 case IIO_EV_DIR_FALLING:
0332 return MAX44009_REG_LOWER_THR;
0333 default:
0334 return -EINVAL;
0335 }
0336 }
0337
0338 static int max44009_write_event_value(struct iio_dev *indio_dev,
0339 const struct iio_chan_spec *chan,
0340 enum iio_event_type type,
0341 enum iio_event_direction dir,
0342 enum iio_event_info info,
0343 int val, int val2)
0344 {
0345 struct max44009_data *data = iio_priv(indio_dev);
0346 int reg, threshold;
0347
0348 if (info != IIO_EV_INFO_VALUE || chan->type != IIO_LIGHT)
0349 return -EINVAL;
0350
0351 threshold = max44009_threshold_byte_from_fraction(val, val2);
0352 if (threshold < 0)
0353 return threshold;
0354
0355 reg = max44009_get_thr_reg(dir);
0356 if (reg < 0)
0357 return reg;
0358
0359 return i2c_smbus_write_byte_data(data->client, reg, threshold);
0360 }
0361
0362 static int max44009_read_threshold(struct iio_dev *indio_dev,
0363 enum iio_event_direction dir)
0364 {
0365 struct max44009_data *data = iio_priv(indio_dev);
0366 int byte, reg;
0367 int mantissa, exponent;
0368
0369 reg = max44009_get_thr_reg(dir);
0370 if (reg < 0)
0371 return reg;
0372
0373 byte = i2c_smbus_read_byte_data(data->client, reg);
0374 if (byte < 0)
0375 return byte;
0376
0377 mantissa = byte & MAX44009_THRESH_MANT_MASK;
0378 mantissa <<= MAX44009_THRESH_MANT_LSHIFT;
0379
0380
0381
0382
0383
0384 if (dir == IIO_EV_DIR_RISING)
0385 mantissa += MAX44009_UPPER_THR_MINIMUM;
0386
0387
0388
0389
0390
0391 exponent = byte & MAX44009_THRESH_EXP_MASK;
0392 exponent >>= MAX44009_THRESH_EXP_RSHIFT;
0393
0394 return (1 << exponent) * mantissa;
0395 }
0396
0397 static int max44009_read_event_value(struct iio_dev *indio_dev,
0398 const struct iio_chan_spec *chan,
0399 enum iio_event_type type,
0400 enum iio_event_direction dir,
0401 enum iio_event_info info,
0402 int *val, int *val2)
0403 {
0404 int ret;
0405 int threshold;
0406
0407 if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH)
0408 return -EINVAL;
0409
0410 ret = max44009_read_threshold(indio_dev, dir);
0411 if (ret < 0)
0412 return ret;
0413 threshold = ret;
0414
0415 *val = threshold * MAX44009_SCALE_NUMERATOR;
0416 *val2 = MAX44009_SCALE_DENOMINATOR;
0417
0418 return IIO_VAL_FRACTIONAL;
0419 }
0420
0421 static int max44009_write_event_config(struct iio_dev *indio_dev,
0422 const struct iio_chan_spec *chan,
0423 enum iio_event_type type,
0424 enum iio_event_direction dir,
0425 int state)
0426 {
0427 struct max44009_data *data = iio_priv(indio_dev);
0428 int ret;
0429
0430 if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH)
0431 return -EINVAL;
0432
0433 ret = i2c_smbus_write_byte_data(data->client,
0434 MAX44009_REG_INT_EN, state);
0435 if (ret < 0)
0436 return ret;
0437
0438
0439
0440
0441
0442 return i2c_smbus_write_byte_data(data->client,
0443 MAX44009_REG_THR_TIMER, 0);
0444 }
0445
0446 static int max44009_read_event_config(struct iio_dev *indio_dev,
0447 const struct iio_chan_spec *chan,
0448 enum iio_event_type type,
0449 enum iio_event_direction dir)
0450 {
0451 struct max44009_data *data = iio_priv(indio_dev);
0452
0453 if (chan->type != IIO_LIGHT || type != IIO_EV_TYPE_THRESH)
0454 return -EINVAL;
0455
0456 return i2c_smbus_read_byte_data(data->client, MAX44009_REG_INT_EN);
0457 }
0458
0459 static const struct iio_info max44009_info = {
0460 .read_raw = max44009_read_raw,
0461 .write_raw = max44009_write_raw,
0462 .write_raw_get_fmt = max44009_write_raw_get_fmt,
0463 .read_event_value = max44009_read_event_value,
0464 .read_event_config = max44009_read_event_config,
0465 .write_event_value = max44009_write_event_value,
0466 .write_event_config = max44009_write_event_config,
0467 .attrs = &max44009_attribute_group,
0468 };
0469
0470 static irqreturn_t max44009_threaded_irq_handler(int irq, void *p)
0471 {
0472 struct iio_dev *indio_dev = p;
0473 struct max44009_data *data = iio_priv(indio_dev);
0474 int ret;
0475
0476 ret = i2c_smbus_read_byte_data(data->client, MAX44009_REG_INT_STATUS);
0477 if (ret) {
0478 iio_push_event(indio_dev,
0479 IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
0480 IIO_EV_TYPE_THRESH,
0481 IIO_EV_DIR_EITHER),
0482 iio_get_time_ns(indio_dev));
0483
0484 return IRQ_HANDLED;
0485 }
0486
0487 return IRQ_NONE;
0488 }
0489
0490 static int max44009_probe(struct i2c_client *client,
0491 const struct i2c_device_id *id)
0492 {
0493 struct max44009_data *data;
0494 struct iio_dev *indio_dev;
0495 int ret;
0496
0497 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0498 if (!indio_dev)
0499 return -ENOMEM;
0500
0501 data = iio_priv(indio_dev);
0502 i2c_set_clientdata(client, indio_dev);
0503 data->client = client;
0504 indio_dev->info = &max44009_info;
0505 indio_dev->modes = INDIO_DIRECT_MODE;
0506 indio_dev->name = MAX44009_DRV_NAME;
0507 indio_dev->channels = max44009_channels;
0508 indio_dev->num_channels = ARRAY_SIZE(max44009_channels);
0509 mutex_init(&data->lock);
0510
0511
0512 ret = i2c_smbus_read_byte_data(client, MAX44009_REG_CFG);
0513 if (ret < 0)
0514 return ret;
0515
0516 if (client->irq > 0) {
0517 ret = devm_request_threaded_irq(&client->dev, client->irq,
0518 NULL,
0519 max44009_threaded_irq_handler,
0520 IRQF_TRIGGER_FALLING |
0521 IRQF_ONESHOT | IRQF_SHARED,
0522 "max44009_event",
0523 indio_dev);
0524 if (ret < 0)
0525 return ret;
0526 }
0527
0528 return devm_iio_device_register(&client->dev, indio_dev);
0529 }
0530
0531 static const struct i2c_device_id max44009_id[] = {
0532 { "max44009", 0 },
0533 { }
0534 };
0535 MODULE_DEVICE_TABLE(i2c, max44009_id);
0536
0537 static struct i2c_driver max44009_driver = {
0538 .driver = {
0539 .name = MAX44009_DRV_NAME,
0540 },
0541 .probe = max44009_probe,
0542 .id_table = max44009_id,
0543 };
0544 module_i2c_driver(max44009_driver);
0545
0546 static const struct of_device_id max44009_of_match[] = {
0547 { .compatible = "maxim,max44009" },
0548 { }
0549 };
0550 MODULE_DEVICE_TABLE(of, max44009_of_match);
0551
0552 MODULE_AUTHOR("Robert Eshleman <bobbyeshleman@gmail.com>");
0553 MODULE_LICENSE("GPL v2");
0554 MODULE_DESCRIPTION("MAX44009 ambient light sensor driver");