584 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * LTRF216A Ambient Light Sensor4 *5 * Copyright (C) 2022 Collabora, Ltd.6 * Author: Shreeya Patel <shreeya.patel@collabora.com>7 *8 * Copyright (C) 2021 Lite-On Technology Corp (Singapore)9 * Author: Shi Zhigang <Zhigang.Shi@liteon.com>10 *11 * IIO driver for LTRF216A (7-bit I2C slave address 0x53).12 */13 14#include <linux/bitfield.h>15#include <linux/bits.h>16#include <linux/delay.h>17#include <linux/i2c.h>18#include <linux/init.h>19#include <linux/iopoll.h>20#include <linux/mod_devicetable.h>21#include <linux/module.h>22#include <linux/mutex.h>23#include <linux/pm.h>24#include <linux/pm_runtime.h>25#include <linux/regmap.h>26 27#include <linux/iio/iio.h>28 29#include <linux/unaligned.h>30 31#define LTRF216A_ALS_RESET_MASK BIT(4)32#define LTRF216A_ALS_DATA_STATUS BIT(3)33#define LTRF216A_ALS_ENABLE_MASK BIT(1)34#define LTRF216A_MAIN_CTRL 0x0035#define LTRF216A_ALS_MEAS_RES 0x0436#define LTRF216A_ALS_GAIN 0x0537#define LTRF216A_PART_ID 0x0638#define LTRF216A_MAIN_STATUS 0x0739#define LTRF216A_ALS_CLEAR_DATA_0 0x0a40#define LTRF216A_ALS_CLEAR_DATA_1 0x0b41#define LTRF216A_ALS_CLEAR_DATA_2 0x0c42#define LTRF216A_ALS_DATA_0 0x0d43#define LTRF216A_ALS_DATA_1 0x0e44#define LTRF216A_ALS_DATA_2 0x0f45#define LTRF216A_INT_CFG 0x1946#define LTRF216A_INT_PST 0x1a47#define LTRF216A_ALS_THRES_UP_0 0x2148#define LTRF216A_ALS_THRES_UP_1 0x2249#define LTRF216A_ALS_THRES_UP_2 0x2350#define LTRF216A_ALS_THRES_LOW_0 0x2451#define LTRF216A_ALS_THRES_LOW_1 0x2552#define LTRF216A_ALS_THRES_LOW_2 0x2653#define LTRF216A_ALS_READ_DATA_DELAY_US 2000054 55static const int ltrf216a_int_time_available[][2] = {56 { 0, 400000 },57 { 0, 200000 },58 { 0, 100000 },59 { 0, 50000 },60 { 0, 25000 },61};62 63static const int ltrf216a_int_time_reg[][2] = {64 { 400, 0x03 },65 { 200, 0x13 },66 { 100, 0x22 },67 { 50, 0x31 },68 { 25, 0x40 },69};70 71struct ltr_chip_info {72 /* Chip contains CLEAR_DATA_0/1/2 registers at offset 0xa..0xc */73 bool has_clear_data;74 /* Lux calculation multiplier for ALS data */75 int lux_multiplier;76};77 78/*79 * Window Factor is needed when the device is under Window glass80 * with coated tinted ink. This is to compensate for the light loss81 * due to the lower transmission rate of the window glass and helps82 * in calculating lux.83 */84#define LTRF216A_WIN_FAC 185 86struct ltrf216a_data {87 struct regmap *regmap;88 struct i2c_client *client;89 const struct ltr_chip_info *info;90 u32 int_time;91 u16 int_time_fac;92 u8 als_gain_fac;93 /*94 * Protects regmap accesses and makes sure integration time95 * remains constant during the measurement of lux.96 */97 struct mutex lock;98};99 100static const struct iio_chan_spec ltrf216a_channels[] = {101 {102 .type = IIO_LIGHT,103 .info_mask_separate =104 BIT(IIO_CHAN_INFO_RAW) |105 BIT(IIO_CHAN_INFO_PROCESSED) |106 BIT(IIO_CHAN_INFO_INT_TIME),107 .info_mask_separate_available =108 BIT(IIO_CHAN_INFO_INT_TIME),109 },110};111 112static void ltrf216a_reset(struct iio_dev *indio_dev)113{114 struct ltrf216a_data *data = iio_priv(indio_dev);115 116 /* reset sensor, chip fails to respond to this, so ignore any errors */117 regmap_write(data->regmap, LTRF216A_MAIN_CTRL, LTRF216A_ALS_RESET_MASK);118 119 /* reset time */120 usleep_range(1000, 2000);121}122 123static int ltrf216a_enable(struct iio_dev *indio_dev)124{125 struct ltrf216a_data *data = iio_priv(indio_dev);126 struct device *dev = &data->client->dev;127 int ret;128 129 /* enable sensor */130 ret = regmap_set_bits(data->regmap,131 LTRF216A_MAIN_CTRL, LTRF216A_ALS_ENABLE_MASK);132 if (ret) {133 dev_err(dev, "failed to enable sensor: %d\n", ret);134 return ret;135 }136 137 /* sleep for one integration cycle after enabling the device */138 msleep(ltrf216a_int_time_reg[0][0]);139 140 return 0;141}142 143static int ltrf216a_disable(struct iio_dev *indio_dev)144{145 struct ltrf216a_data *data = iio_priv(indio_dev);146 struct device *dev = &data->client->dev;147 int ret;148 149 ret = regmap_write(data->regmap, LTRF216A_MAIN_CTRL, 0);150 if (ret)151 dev_err(dev, "failed to disable sensor: %d\n", ret);152 153 return ret;154}155 156static void ltrf216a_cleanup(void *data)157{158 struct iio_dev *indio_dev = data;159 160 ltrf216a_disable(indio_dev);161}162 163static int ltrf216a_set_int_time(struct ltrf216a_data *data, int itime)164{165 struct device *dev = &data->client->dev;166 unsigned int i;167 u8 reg_val;168 int ret;169 170 for (i = 0; i < ARRAY_SIZE(ltrf216a_int_time_available); i++) {171 if (ltrf216a_int_time_available[i][1] == itime)172 break;173 }174 if (i == ARRAY_SIZE(ltrf216a_int_time_available))175 return -EINVAL;176 177 reg_val = ltrf216a_int_time_reg[i][1];178 179 ret = regmap_write(data->regmap, LTRF216A_ALS_MEAS_RES, reg_val);180 if (ret) {181 dev_err(dev, "failed to set integration time: %d\n", ret);182 return ret;183 }184 185 data->int_time_fac = ltrf216a_int_time_reg[i][0];186 data->int_time = itime;187 188 return 0;189}190 191static int ltrf216a_get_int_time(struct ltrf216a_data *data,192 int *val, int *val2)193{194 *val = 0;195 *val2 = data->int_time;196 return IIO_VAL_INT_PLUS_MICRO;197}198 199static int ltrf216a_set_power_state(struct ltrf216a_data *data, bool on)200{201 struct device *dev = &data->client->dev;202 int ret = 0;203 204 if (on) {205 ret = pm_runtime_resume_and_get(dev);206 if (ret) {207 dev_err(dev, "failed to resume runtime PM: %d\n", ret);208 return ret;209 }210 } else {211 pm_runtime_mark_last_busy(dev);212 pm_runtime_put_autosuspend(dev);213 }214 215 return ret;216}217 218static int ltrf216a_read_data(struct ltrf216a_data *data, u8 addr)219{220 struct device *dev = &data->client->dev;221 int ret, val;222 u8 buf[3];223 224 ret = regmap_read_poll_timeout(data->regmap, LTRF216A_MAIN_STATUS,225 val, val & LTRF216A_ALS_DATA_STATUS,226 LTRF216A_ALS_READ_DATA_DELAY_US,227 LTRF216A_ALS_READ_DATA_DELAY_US * 50);228 if (ret) {229 dev_err(dev, "failed to wait for measurement data: %d\n", ret);230 return ret;231 }232 233 ret = regmap_bulk_read(data->regmap, addr, buf, sizeof(buf));234 if (ret) {235 dev_err(dev, "failed to read measurement data: %d\n", ret);236 return ret;237 }238 239 return get_unaligned_le24(&buf[0]);240}241 242static int ltrf216a_get_lux(struct ltrf216a_data *data)243{244 int ret, greendata;245 u64 lux;246 247 ret = ltrf216a_set_power_state(data, true);248 if (ret)249 return ret;250 251 greendata = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0);252 if (greendata < 0)253 return greendata;254 255 ltrf216a_set_power_state(data, false);256 257 lux = greendata * data->info->lux_multiplier * LTRF216A_WIN_FAC;258 259 return lux;260}261 262static int ltrf216a_read_raw(struct iio_dev *indio_dev,263 struct iio_chan_spec const *chan, int *val,264 int *val2, long mask)265{266 struct ltrf216a_data *data = iio_priv(indio_dev);267 int ret;268 269 switch (mask) {270 case IIO_CHAN_INFO_RAW:271 ret = ltrf216a_set_power_state(data, true);272 if (ret)273 return ret;274 mutex_lock(&data->lock);275 ret = ltrf216a_read_data(data, LTRF216A_ALS_DATA_0);276 mutex_unlock(&data->lock);277 ltrf216a_set_power_state(data, false);278 if (ret < 0)279 return ret;280 *val = ret;281 return IIO_VAL_INT;282 case IIO_CHAN_INFO_PROCESSED:283 mutex_lock(&data->lock);284 ret = ltrf216a_get_lux(data);285 mutex_unlock(&data->lock);286 if (ret < 0)287 return ret;288 *val = ret;289 *val2 = data->als_gain_fac * data->int_time_fac;290 return IIO_VAL_FRACTIONAL;291 case IIO_CHAN_INFO_INT_TIME:292 mutex_lock(&data->lock);293 ret = ltrf216a_get_int_time(data, val, val2);294 mutex_unlock(&data->lock);295 return ret;296 default:297 return -EINVAL;298 }299}300 301static int ltrf216a_write_raw(struct iio_dev *indio_dev,302 struct iio_chan_spec const *chan, int val,303 int val2, long mask)304{305 struct ltrf216a_data *data = iio_priv(indio_dev);306 int ret;307 308 switch (mask) {309 case IIO_CHAN_INFO_INT_TIME:310 if (val != 0)311 return -EINVAL;312 mutex_lock(&data->lock);313 ret = ltrf216a_set_int_time(data, val2);314 mutex_unlock(&data->lock);315 return ret;316 default:317 return -EINVAL;318 }319}320 321static int ltrf216a_read_available(struct iio_dev *indio_dev,322 struct iio_chan_spec const *chan,323 const int **vals, int *type, int *length,324 long mask)325{326 switch (mask) {327 case IIO_CHAN_INFO_INT_TIME:328 *length = ARRAY_SIZE(ltrf216a_int_time_available) * 2;329 *vals = (const int *)ltrf216a_int_time_available;330 *type = IIO_VAL_INT_PLUS_MICRO;331 return IIO_AVAIL_LIST;332 default:333 return -EINVAL;334 }335}336 337static const struct iio_info ltrf216a_info = {338 .read_raw = ltrf216a_read_raw,339 .write_raw = ltrf216a_write_raw,340 .read_avail = ltrf216a_read_available,341};342 343static bool ltrf216a_readable_reg(struct device *dev, unsigned int reg)344{345 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));346 struct ltrf216a_data *data = iio_priv(indio_dev);347 348 switch (reg) {349 case LTRF216A_MAIN_CTRL:350 case LTRF216A_ALS_MEAS_RES:351 case LTRF216A_ALS_GAIN:352 case LTRF216A_PART_ID:353 case LTRF216A_MAIN_STATUS:354 case LTRF216A_ALS_DATA_0:355 case LTRF216A_ALS_DATA_1:356 case LTRF216A_ALS_DATA_2:357 case LTRF216A_INT_CFG:358 case LTRF216A_INT_PST:359 case LTRF216A_ALS_THRES_UP_0:360 case LTRF216A_ALS_THRES_UP_1:361 case LTRF216A_ALS_THRES_UP_2:362 case LTRF216A_ALS_THRES_LOW_0:363 case LTRF216A_ALS_THRES_LOW_1:364 case LTRF216A_ALS_THRES_LOW_2:365 return true;366 case LTRF216A_ALS_CLEAR_DATA_0:367 case LTRF216A_ALS_CLEAR_DATA_1:368 case LTRF216A_ALS_CLEAR_DATA_2:369 return data->info->has_clear_data;370 default:371 return false;372 }373}374 375static bool ltrf216a_writable_reg(struct device *dev, unsigned int reg)376{377 switch (reg) {378 case LTRF216A_MAIN_CTRL:379 case LTRF216A_ALS_MEAS_RES:380 case LTRF216A_ALS_GAIN:381 case LTRF216A_INT_CFG:382 case LTRF216A_INT_PST:383 case LTRF216A_ALS_THRES_UP_0:384 case LTRF216A_ALS_THRES_UP_1:385 case LTRF216A_ALS_THRES_UP_2:386 case LTRF216A_ALS_THRES_LOW_0:387 case LTRF216A_ALS_THRES_LOW_1:388 case LTRF216A_ALS_THRES_LOW_2:389 return true;390 default:391 return false;392 }393}394 395static bool ltrf216a_volatile_reg(struct device *dev, unsigned int reg)396{397 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));398 struct ltrf216a_data *data = iio_priv(indio_dev);399 400 switch (reg) {401 case LTRF216A_MAIN_STATUS:402 case LTRF216A_ALS_DATA_0:403 case LTRF216A_ALS_DATA_1:404 case LTRF216A_ALS_DATA_2:405 return true;406 /*407 * If these registers are not present on a chip (like LTR-308),408 * the missing registers are not considered volatile.409 */410 case LTRF216A_ALS_CLEAR_DATA_0:411 case LTRF216A_ALS_CLEAR_DATA_1:412 case LTRF216A_ALS_CLEAR_DATA_2:413 return data->info->has_clear_data;414 default:415 return false;416 }417}418 419static bool ltrf216a_precious_reg(struct device *dev, unsigned int reg)420{421 return reg == LTRF216A_MAIN_STATUS;422}423 424static const struct regmap_config ltrf216a_regmap_config = {425 .name = "ltrf216a",426 .reg_bits = 8,427 .val_bits = 8,428 .cache_type = REGCACHE_RBTREE,429 .max_register = LTRF216A_ALS_THRES_LOW_2,430 .readable_reg = ltrf216a_readable_reg,431 .writeable_reg = ltrf216a_writable_reg,432 .volatile_reg = ltrf216a_volatile_reg,433 .precious_reg = ltrf216a_precious_reg,434 .disable_locking = true,435};436 437static int ltrf216a_probe(struct i2c_client *client)438{439 struct ltrf216a_data *data;440 struct iio_dev *indio_dev;441 int ret;442 443 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));444 if (!indio_dev)445 return -ENOMEM;446 447 data = iio_priv(indio_dev);448 449 data->regmap = devm_regmap_init_i2c(client, <rf216a_regmap_config);450 if (IS_ERR(data->regmap))451 return dev_err_probe(&client->dev, PTR_ERR(data->regmap),452 "regmap initialization failed\n");453 454 i2c_set_clientdata(client, indio_dev);455 data->client = client;456 data->info = i2c_get_match_data(client);457 458 mutex_init(&data->lock);459 460 indio_dev->info = <rf216a_info;461 indio_dev->name = "ltrf216a";462 indio_dev->channels = ltrf216a_channels;463 indio_dev->num_channels = ARRAY_SIZE(ltrf216a_channels);464 indio_dev->modes = INDIO_DIRECT_MODE;465 466 ret = pm_runtime_set_active(&client->dev);467 if (ret)468 return ret;469 470 /* reset sensor, chip fails to respond to this, so ignore any errors */471 ltrf216a_reset(indio_dev);472 473 ret = regmap_reinit_cache(data->regmap, <rf216a_regmap_config);474 if (ret)475 return dev_err_probe(&client->dev, ret,476 "failed to reinit regmap cache\n");477 478 ret = ltrf216a_enable(indio_dev);479 if (ret)480 return ret;481 482 ret = devm_add_action_or_reset(&client->dev, ltrf216a_cleanup,483 indio_dev);484 if (ret)485 return ret;486 487 ret = devm_pm_runtime_enable(&client->dev);488 if (ret)489 return dev_err_probe(&client->dev, ret,490 "failed to enable runtime PM\n");491 492 pm_runtime_set_autosuspend_delay(&client->dev, 1000);493 pm_runtime_use_autosuspend(&client->dev);494 495 data->int_time = 100000;496 data->int_time_fac = 100;497 data->als_gain_fac = 3;498 499 return devm_iio_device_register(&client->dev, indio_dev);500}501 502static int ltrf216a_runtime_suspend(struct device *dev)503{504 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));505 struct ltrf216a_data *data = iio_priv(indio_dev);506 int ret;507 508 ret = ltrf216a_disable(indio_dev);509 if (ret)510 return ret;511 512 regcache_cache_only(data->regmap, true);513 514 return 0;515}516 517static int ltrf216a_runtime_resume(struct device *dev)518{519 struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));520 struct ltrf216a_data *data = iio_priv(indio_dev);521 int ret;522 523 regcache_cache_only(data->regmap, false);524 regcache_mark_dirty(data->regmap);525 ret = regcache_sync(data->regmap);526 if (ret)527 goto cache_only;528 529 ret = ltrf216a_enable(indio_dev);530 if (ret)531 goto cache_only;532 533 return 0;534 535cache_only:536 regcache_cache_only(data->regmap, true);537 538 return ret;539}540 541static DEFINE_RUNTIME_DEV_PM_OPS(ltrf216a_pm_ops, ltrf216a_runtime_suspend,542 ltrf216a_runtime_resume, NULL);543 544static const struct ltr_chip_info ltr308_chip_info = {545 .has_clear_data = false,546 .lux_multiplier = 60,547};548 549static const struct ltr_chip_info ltrf216a_chip_info = {550 .has_clear_data = true,551 .lux_multiplier = 45,552};553 554static const struct i2c_device_id ltrf216a_id[] = {555 { "ltr308", .driver_data = (kernel_ulong_t)<r308_chip_info },556 { "ltrf216a", .driver_data = (kernel_ulong_t)<rf216a_chip_info },557 {}558};559MODULE_DEVICE_TABLE(i2c, ltrf216a_id);560 561static const struct of_device_id ltrf216a_of_match[] = {562 { .compatible = "liteon,ltr308", .data = <r308_chip_info },563 { .compatible = "liteon,ltrf216a", .data = <rf216a_chip_info },564 { .compatible = "ltr,ltrf216a", .data = <rf216a_chip_info },565 {}566};567MODULE_DEVICE_TABLE(of, ltrf216a_of_match);568 569static struct i2c_driver ltrf216a_driver = {570 .driver = {571 .name = "ltrf216a",572 .pm = pm_ptr(<rf216a_pm_ops),573 .of_match_table = ltrf216a_of_match,574 },575 .probe = ltrf216a_probe,576 .id_table = ltrf216a_id,577};578module_i2c_driver(ltrf216a_driver);579 580MODULE_AUTHOR("Shreeya Patel <shreeya.patel@collabora.com>");581MODULE_AUTHOR("Shi Zhigang <Zhigang.Shi@liteon.com>");582MODULE_DESCRIPTION("LTRF216A ambient light sensor driver");583MODULE_LICENSE("GPL");584