0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/slab.h>
0010 #include <linux/pm.h>
0011 #include <linux/i2c.h>
0012 #include <linux/err.h>
0013 #include <linux/mutex.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/iio/iio.h>
0016 #include <linux/iio/sysfs.h>
0017 #include <linux/iio/events.h>
0018
0019 #define APDS9300_DRV_NAME "apds9300"
0020 #define APDS9300_IRQ_NAME "apds9300_event"
0021
0022
0023 #define APDS9300_CMD BIT(7)
0024 #define APDS9300_WORD BIT(5)
0025 #define APDS9300_CLEAR BIT(6)
0026
0027
0028 #define APDS9300_CONTROL 0x00
0029 #define APDS9300_THRESHLOWLOW 0x02
0030 #define APDS9300_THRESHHIGHLOW 0x04
0031 #define APDS9300_INTERRUPT 0x06
0032 #define APDS9300_DATA0LOW 0x0c
0033 #define APDS9300_DATA1LOW 0x0e
0034
0035
0036 #define APDS9300_POWER_ON 0x03
0037 #define APDS9300_POWER_OFF 0x00
0038
0039
0040 #define APDS9300_INTR_ENABLE 0x10
0041
0042 #define APDS9300_THRESH_INTR 0x01
0043
0044 #define APDS9300_THRESH_MAX 0xffff
0045
0046 struct apds9300_data {
0047 struct i2c_client *client;
0048 struct mutex mutex;
0049 int power_state;
0050 int thresh_low;
0051 int thresh_hi;
0052 int intr_en;
0053 };
0054
0055
0056
0057
0058 static const u16 apds9300_lux_ratio[] = {
0059 0, 2, 4, 7, 11, 15, 19, 24, 29, 34, 40, 45, 51, 57, 64, 70, 77, 84, 91,
0060 98, 105, 112, 120, 128, 136, 144, 152, 160, 168, 177, 185, 194, 203,
0061 212, 221, 230, 239, 249, 258, 268, 277, 287, 297, 307, 317, 327, 337,
0062 347, 358, 368, 379, 390, 400,
0063 };
0064
0065 static unsigned long apds9300_calculate_lux(u16 ch0, u16 ch1)
0066 {
0067 unsigned long lux, tmp;
0068
0069
0070 if (ch0 == 0)
0071 return 0;
0072
0073 tmp = DIV_ROUND_UP(ch1 * 100, ch0);
0074 if (tmp <= 52) {
0075 lux = 3150 * ch0 - (unsigned long)DIV_ROUND_UP_ULL(ch0
0076 * apds9300_lux_ratio[tmp] * 5930ull, 1000);
0077 } else if (tmp <= 65) {
0078 lux = 2290 * ch0 - 2910 * ch1;
0079 } else if (tmp <= 80) {
0080 lux = 1570 * ch0 - 1800 * ch1;
0081 } else if (tmp <= 130) {
0082 lux = 338 * ch0 - 260 * ch1;
0083 } else {
0084 lux = 0;
0085 }
0086
0087 return lux / 100000;
0088 }
0089
0090 static int apds9300_get_adc_val(struct apds9300_data *data, int adc_number)
0091 {
0092 int ret;
0093 u8 flags = APDS9300_CMD | APDS9300_WORD;
0094
0095 if (!data->power_state)
0096 return -EBUSY;
0097
0098
0099 flags |= adc_number ? APDS9300_DATA1LOW : APDS9300_DATA0LOW;
0100
0101 ret = i2c_smbus_read_word_data(data->client, flags);
0102 if (ret < 0)
0103 dev_err(&data->client->dev,
0104 "failed to read ADC%d value\n", adc_number);
0105
0106 return ret;
0107 }
0108
0109 static int apds9300_set_thresh_low(struct apds9300_data *data, int value)
0110 {
0111 int ret;
0112
0113 if (!data->power_state)
0114 return -EBUSY;
0115
0116 if (value > APDS9300_THRESH_MAX)
0117 return -EINVAL;
0118
0119 ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHLOWLOW
0120 | APDS9300_CMD | APDS9300_WORD, value);
0121 if (ret) {
0122 dev_err(&data->client->dev, "failed to set thresh_low\n");
0123 return ret;
0124 }
0125 data->thresh_low = value;
0126
0127 return 0;
0128 }
0129
0130 static int apds9300_set_thresh_hi(struct apds9300_data *data, int value)
0131 {
0132 int ret;
0133
0134 if (!data->power_state)
0135 return -EBUSY;
0136
0137 if (value > APDS9300_THRESH_MAX)
0138 return -EINVAL;
0139
0140 ret = i2c_smbus_write_word_data(data->client, APDS9300_THRESHHIGHLOW
0141 | APDS9300_CMD | APDS9300_WORD, value);
0142 if (ret) {
0143 dev_err(&data->client->dev, "failed to set thresh_hi\n");
0144 return ret;
0145 }
0146 data->thresh_hi = value;
0147
0148 return 0;
0149 }
0150
0151 static int apds9300_set_intr_state(struct apds9300_data *data, int state)
0152 {
0153 int ret;
0154 u8 cmd;
0155
0156 if (!data->power_state)
0157 return -EBUSY;
0158
0159 cmd = state ? APDS9300_INTR_ENABLE | APDS9300_THRESH_INTR : 0x00;
0160 ret = i2c_smbus_write_byte_data(data->client,
0161 APDS9300_INTERRUPT | APDS9300_CMD, cmd);
0162 if (ret) {
0163 dev_err(&data->client->dev,
0164 "failed to set interrupt state %d\n", state);
0165 return ret;
0166 }
0167 data->intr_en = state;
0168
0169 return 0;
0170 }
0171
0172 static int apds9300_set_power_state(struct apds9300_data *data, int state)
0173 {
0174 int ret;
0175 u8 cmd;
0176
0177 cmd = state ? APDS9300_POWER_ON : APDS9300_POWER_OFF;
0178 ret = i2c_smbus_write_byte_data(data->client,
0179 APDS9300_CONTROL | APDS9300_CMD, cmd);
0180 if (ret) {
0181 dev_err(&data->client->dev,
0182 "failed to set power state %d\n", state);
0183 return ret;
0184 }
0185 data->power_state = state;
0186
0187 return 0;
0188 }
0189
0190 static void apds9300_clear_intr(struct apds9300_data *data)
0191 {
0192 int ret;
0193
0194 ret = i2c_smbus_write_byte(data->client, APDS9300_CLEAR | APDS9300_CMD);
0195 if (ret < 0)
0196 dev_err(&data->client->dev, "failed to clear interrupt\n");
0197 }
0198
0199 static int apds9300_chip_init(struct apds9300_data *data)
0200 {
0201 int ret;
0202
0203
0204 ret = apds9300_set_power_state(data, 0);
0205 if (ret < 0)
0206 goto err;
0207
0208
0209
0210
0211 ret = apds9300_set_power_state(data, 1);
0212 if (ret < 0)
0213 goto err;
0214 ret = i2c_smbus_read_byte_data(data->client,
0215 APDS9300_CONTROL | APDS9300_CMD);
0216 if (ret != APDS9300_POWER_ON) {
0217 ret = -ENODEV;
0218 goto err;
0219 }
0220
0221
0222
0223
0224 ret = apds9300_set_intr_state(data, 0);
0225 if (ret < 0)
0226 goto err;
0227
0228 return 0;
0229
0230 err:
0231 dev_err(&data->client->dev, "failed to init the chip\n");
0232 return ret;
0233 }
0234
0235 static int apds9300_read_raw(struct iio_dev *indio_dev,
0236 struct iio_chan_spec const *chan, int *val, int *val2,
0237 long mask)
0238 {
0239 int ch0, ch1, ret = -EINVAL;
0240 struct apds9300_data *data = iio_priv(indio_dev);
0241
0242 mutex_lock(&data->mutex);
0243 switch (chan->type) {
0244 case IIO_LIGHT:
0245 ch0 = apds9300_get_adc_val(data, 0);
0246 if (ch0 < 0) {
0247 ret = ch0;
0248 break;
0249 }
0250 ch1 = apds9300_get_adc_val(data, 1);
0251 if (ch1 < 0) {
0252 ret = ch1;
0253 break;
0254 }
0255 *val = apds9300_calculate_lux(ch0, ch1);
0256 ret = IIO_VAL_INT;
0257 break;
0258 case IIO_INTENSITY:
0259 ret = apds9300_get_adc_val(data, chan->channel);
0260 if (ret < 0)
0261 break;
0262 *val = ret;
0263 ret = IIO_VAL_INT;
0264 break;
0265 default:
0266 break;
0267 }
0268 mutex_unlock(&data->mutex);
0269
0270 return ret;
0271 }
0272
0273 static int apds9300_read_thresh(struct iio_dev *indio_dev,
0274 const struct iio_chan_spec *chan, enum iio_event_type type,
0275 enum iio_event_direction dir, enum iio_event_info info,
0276 int *val, int *val2)
0277 {
0278 struct apds9300_data *data = iio_priv(indio_dev);
0279
0280 switch (dir) {
0281 case IIO_EV_DIR_RISING:
0282 *val = data->thresh_hi;
0283 break;
0284 case IIO_EV_DIR_FALLING:
0285 *val = data->thresh_low;
0286 break;
0287 default:
0288 return -EINVAL;
0289 }
0290
0291 return IIO_VAL_INT;
0292 }
0293
0294 static int apds9300_write_thresh(struct iio_dev *indio_dev,
0295 const struct iio_chan_spec *chan, enum iio_event_type type,
0296 enum iio_event_direction dir, enum iio_event_info info, int val,
0297 int val2)
0298 {
0299 struct apds9300_data *data = iio_priv(indio_dev);
0300 int ret;
0301
0302 mutex_lock(&data->mutex);
0303 if (dir == IIO_EV_DIR_RISING)
0304 ret = apds9300_set_thresh_hi(data, val);
0305 else
0306 ret = apds9300_set_thresh_low(data, val);
0307 mutex_unlock(&data->mutex);
0308
0309 return ret;
0310 }
0311
0312 static int apds9300_read_interrupt_config(struct iio_dev *indio_dev,
0313 const struct iio_chan_spec *chan,
0314 enum iio_event_type type,
0315 enum iio_event_direction dir)
0316 {
0317 struct apds9300_data *data = iio_priv(indio_dev);
0318
0319 return data->intr_en;
0320 }
0321
0322 static int apds9300_write_interrupt_config(struct iio_dev *indio_dev,
0323 const struct iio_chan_spec *chan, enum iio_event_type type,
0324 enum iio_event_direction dir, int state)
0325 {
0326 struct apds9300_data *data = iio_priv(indio_dev);
0327 int ret;
0328
0329 mutex_lock(&data->mutex);
0330 ret = apds9300_set_intr_state(data, state);
0331 mutex_unlock(&data->mutex);
0332
0333 return ret;
0334 }
0335
0336 static const struct iio_info apds9300_info_no_irq = {
0337 .read_raw = apds9300_read_raw,
0338 };
0339
0340 static const struct iio_info apds9300_info = {
0341 .read_raw = apds9300_read_raw,
0342 .read_event_value = apds9300_read_thresh,
0343 .write_event_value = apds9300_write_thresh,
0344 .read_event_config = apds9300_read_interrupt_config,
0345 .write_event_config = apds9300_write_interrupt_config,
0346 };
0347
0348 static const struct iio_event_spec apds9300_event_spec[] = {
0349 {
0350 .type = IIO_EV_TYPE_THRESH,
0351 .dir = IIO_EV_DIR_RISING,
0352 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0353 BIT(IIO_EV_INFO_ENABLE),
0354 }, {
0355 .type = IIO_EV_TYPE_THRESH,
0356 .dir = IIO_EV_DIR_FALLING,
0357 .mask_separate = BIT(IIO_EV_INFO_VALUE) |
0358 BIT(IIO_EV_INFO_ENABLE),
0359 },
0360 };
0361
0362 static const struct iio_chan_spec apds9300_channels[] = {
0363 {
0364 .type = IIO_LIGHT,
0365 .channel = 0,
0366 .indexed = true,
0367 .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
0368 }, {
0369 .type = IIO_INTENSITY,
0370 .channel = 0,
0371 .channel2 = IIO_MOD_LIGHT_BOTH,
0372 .indexed = true,
0373 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0374 .event_spec = apds9300_event_spec,
0375 .num_event_specs = ARRAY_SIZE(apds9300_event_spec),
0376 }, {
0377 .type = IIO_INTENSITY,
0378 .channel = 1,
0379 .channel2 = IIO_MOD_LIGHT_IR,
0380 .indexed = true,
0381 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
0382 },
0383 };
0384
0385 static irqreturn_t apds9300_interrupt_handler(int irq, void *private)
0386 {
0387 struct iio_dev *dev_info = private;
0388 struct apds9300_data *data = iio_priv(dev_info);
0389
0390 iio_push_event(dev_info,
0391 IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
0392 IIO_EV_TYPE_THRESH,
0393 IIO_EV_DIR_EITHER),
0394 iio_get_time_ns(dev_info));
0395
0396 apds9300_clear_intr(data);
0397
0398 return IRQ_HANDLED;
0399 }
0400
0401 static int apds9300_probe(struct i2c_client *client,
0402 const struct i2c_device_id *id)
0403 {
0404 struct apds9300_data *data;
0405 struct iio_dev *indio_dev;
0406 int ret;
0407
0408 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0409 if (!indio_dev)
0410 return -ENOMEM;
0411
0412 data = iio_priv(indio_dev);
0413 i2c_set_clientdata(client, indio_dev);
0414 data->client = client;
0415
0416 ret = apds9300_chip_init(data);
0417 if (ret < 0)
0418 goto err;
0419
0420 mutex_init(&data->mutex);
0421
0422 indio_dev->channels = apds9300_channels;
0423 indio_dev->num_channels = ARRAY_SIZE(apds9300_channels);
0424 indio_dev->name = APDS9300_DRV_NAME;
0425 indio_dev->modes = INDIO_DIRECT_MODE;
0426
0427 if (client->irq)
0428 indio_dev->info = &apds9300_info;
0429 else
0430 indio_dev->info = &apds9300_info_no_irq;
0431
0432 if (client->irq) {
0433 ret = devm_request_threaded_irq(&client->dev, client->irq,
0434 NULL, apds9300_interrupt_handler,
0435 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0436 APDS9300_IRQ_NAME, indio_dev);
0437 if (ret) {
0438 dev_err(&client->dev, "irq request error %d\n", -ret);
0439 goto err;
0440 }
0441 }
0442
0443 ret = iio_device_register(indio_dev);
0444 if (ret < 0)
0445 goto err;
0446
0447 return 0;
0448
0449 err:
0450
0451 apds9300_set_power_state(data, 0);
0452 return ret;
0453 }
0454
0455 static int apds9300_remove(struct i2c_client *client)
0456 {
0457 struct iio_dev *indio_dev = i2c_get_clientdata(client);
0458 struct apds9300_data *data = iio_priv(indio_dev);
0459
0460 iio_device_unregister(indio_dev);
0461
0462
0463 apds9300_set_intr_state(data, 0);
0464 apds9300_set_power_state(data, 0);
0465
0466 return 0;
0467 }
0468
0469 static int apds9300_suspend(struct device *dev)
0470 {
0471 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0472 struct apds9300_data *data = iio_priv(indio_dev);
0473 int ret;
0474
0475 mutex_lock(&data->mutex);
0476 ret = apds9300_set_power_state(data, 0);
0477 mutex_unlock(&data->mutex);
0478
0479 return ret;
0480 }
0481
0482 static int apds9300_resume(struct device *dev)
0483 {
0484 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
0485 struct apds9300_data *data = iio_priv(indio_dev);
0486 int ret;
0487
0488 mutex_lock(&data->mutex);
0489 ret = apds9300_set_power_state(data, 1);
0490 mutex_unlock(&data->mutex);
0491
0492 return ret;
0493 }
0494
0495 static DEFINE_SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend,
0496 apds9300_resume);
0497
0498 static const struct i2c_device_id apds9300_id[] = {
0499 { APDS9300_DRV_NAME, 0 },
0500 { }
0501 };
0502
0503 MODULE_DEVICE_TABLE(i2c, apds9300_id);
0504
0505 static struct i2c_driver apds9300_driver = {
0506 .driver = {
0507 .name = APDS9300_DRV_NAME,
0508 .pm = pm_sleep_ptr(&apds9300_pm_ops),
0509 },
0510 .probe = apds9300_probe,
0511 .remove = apds9300_remove,
0512 .id_table = apds9300_id,
0513 };
0514
0515 module_i2c_driver(apds9300_driver);
0516
0517 MODULE_AUTHOR("Kravchenko Oleksandr <o.v.kravchenko@globallogic.com>");
0518 MODULE_AUTHOR("GlobalLogic inc.");
0519 MODULE_DESCRIPTION("APDS9300 ambient light photo sensor driver");
0520 MODULE_LICENSE("GPL");