FILE
sx_common.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/proximity/sx_common.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright 2021 Google LLC. 4 * 5 * Common part of most Semtech SAR sensor. 6 */ 7 8#include <linux/bitops.h> 9#include <linux/byteorder/generic.h> 10#include <linux/delay.h> 11#include <linux/device.h> 12#include <linux/err.h> 13#include <linux/export.h> 14#include <linux/interrupt.h> 15#include <linux/irqreturn.h> 16#include <linux/i2c.h> 17#include <linux/kernel.h> 18#include <linux/module.h> 19#include <linux/regmap.h> 20#include <linux/regulator/consumer.h> 21#include <vdso/bits.h> 22 23#include <linux/iio/buffer.h> 24#include <linux/iio/events.h> 25#include <linux/iio/iio.h> 26#include <linux/iio/trigger.h> 27#include <linux/iio/triggered_buffer.h> 28#include <linux/iio/trigger_consumer.h> 29 30#include "sx_common.h" 31 32/* All Semtech SAR sensors have IRQ bit in the same order. */ 33#define SX_COMMON_CONVDONE_IRQ BIT(0) 34#define SX_COMMON_FAR_IRQ BIT(2) 35#define SX_COMMON_CLOSE_IRQ BIT(3) 36 37const struct iio_event_spec sx_common_events[3] = { 38 { 39 .type = IIO_EV_TYPE_THRESH, 40 .dir = IIO_EV_DIR_RISING, 41 .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD), 42 }, 43 { 44 .type = IIO_EV_TYPE_THRESH, 45 .dir = IIO_EV_DIR_FALLING, 46 .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD), 47 }, 48 { 49 .type = IIO_EV_TYPE_THRESH, 50 .dir = IIO_EV_DIR_EITHER, 51 .mask_separate = BIT(IIO_EV_INFO_ENABLE) | 52 BIT(IIO_EV_INFO_HYSTERESIS) | 53 BIT(IIO_EV_INFO_VALUE), 54 }, 55}; 56EXPORT_SYMBOL_NS_GPL(sx_common_events, "SEMTECH_PROX"); 57 58static irqreturn_t sx_common_irq_handler(int irq, void *private) 59{ 60 struct iio_dev *indio_dev = private; 61 struct sx_common_data *data = iio_priv(indio_dev); 62 63 if (data->trigger_enabled) 64 iio_trigger_poll(data->trig); 65 66 /* 67 * Even if no event is enabled, we need to wake the thread to clear the 68 * interrupt state by reading SX_COMMON_REG_IRQ_SRC. 69 * It is not possible to do that here because regmap_read takes a mutex. 70 */ 71 return IRQ_WAKE_THREAD; 72} 73 74static void sx_common_push_events(struct iio_dev *indio_dev) 75{ 76 int ret; 77 unsigned int val, chan; 78 struct sx_common_data *data = iio_priv(indio_dev); 79 s64 timestamp = iio_get_time_ns(indio_dev); 80 unsigned long prox_changed; 81 82 /* Read proximity state on all channels */ 83 ret = regmap_read(data->regmap, data->chip_info->reg_stat, &val); 84 if (ret) { 85 dev_err(&data->client->dev, "i2c transfer error in irq\n"); 86 return; 87 } 88 89 val >>= data->chip_info->stat_offset; 90 91 /* 92 * Only iterate over channels with changes on proximity status that have 93 * events enabled. 94 */ 95 prox_changed = (data->chan_prox_stat ^ val) & data->chan_event; 96 97 for_each_set_bit(chan, &prox_changed, data->chip_info->num_channels) { 98 int dir; 99 u64 ev; 100 101 dir = (val & BIT(chan)) ? IIO_EV_DIR_FALLING : IIO_EV_DIR_RISING; 102 ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, chan, 103 IIO_EV_TYPE_THRESH, dir); 104 105 iio_push_event(indio_dev, ev, timestamp); 106 } 107 data->chan_prox_stat = val; 108} 109 110static int sx_common_enable_irq(struct sx_common_data *data, unsigned int irq) 111{ 112 if (!data->client->irq) 113 return 0; 114 return regmap_set_bits(data->regmap, data->chip_info->reg_irq_msk, 115 irq << data->chip_info->irq_msk_offset); 116} 117 118static int sx_common_disable_irq(struct sx_common_data *data, unsigned int irq) 119{ 120 if (!data->client->irq) 121 return 0; 122 return regmap_clear_bits(data->regmap, data->chip_info->reg_irq_msk, 123 irq << data->chip_info->irq_msk_offset); 124} 125 126static int sx_common_update_chan_en(struct sx_common_data *data, 127 unsigned long chan_read, 128 unsigned long chan_event) 129{ 130 int ret; 131 unsigned long channels = chan_read | chan_event; 132 133 if ((data->chan_read | data->chan_event) != channels) { 134 ret = regmap_update_bits(data->regmap, 135 data->chip_info->reg_enable_chan, 136 data->chip_info->mask_enable_chan, 137 channels); 138 if (ret) 139 return ret; 140 } 141 data->chan_read = chan_read; 142 data->chan_event = chan_event; 143 return 0; 144} 145 146static int sx_common_get_read_channel(struct sx_common_data *data, int channel) 147{ 148 return sx_common_update_chan_en(data, data->chan_read | BIT(channel), 149 data->chan_event); 150} 151 152static int sx_common_put_read_channel(struct sx_common_data *data, int channel) 153{ 154 return sx_common_update_chan_en(data, data->chan_read & ~BIT(channel), 155 data->chan_event); 156} 157 158static int sx_common_get_event_channel(struct sx_common_data *data, int channel) 159{ 160 return sx_common_update_chan_en(data, data->chan_read, 161 data->chan_event | BIT(channel)); 162} 163 164static int sx_common_put_event_channel(struct sx_common_data *data, int channel) 165{ 166 return sx_common_update_chan_en(data, data->chan_read, 167 data->chan_event & ~BIT(channel)); 168} 169 170/** 171 * sx_common_read_proximity() - Read raw proximity value. 172 * @data: Internal data 173 * @chan: Channel to read 174 * @val: pointer to return read value. 175 * 176 * Request a conversion, wait for the sensor to be ready and 177 * return the raw proximity value. 178 */ 179int sx_common_read_proximity(struct sx_common_data *data, 180 const struct iio_chan_spec *chan, int *val) 181{ 182 int ret; 183 __be16 rawval; 184 185 mutex_lock(&data->mutex); 186 187 ret = sx_common_get_read_channel(data, chan->channel); 188 if (ret) 189 goto out; 190 191 ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); 192 if (ret) 193 goto out_put_channel; 194 195 mutex_unlock(&data->mutex); 196 197 if (data->client->irq) { 198 ret = wait_for_completion_interruptible(&data->completion); 199 reinit_completion(&data->completion); 200 } else { 201 ret = data->chip_info->ops.wait_for_sample(data); 202 } 203 204 mutex_lock(&data->mutex); 205 206 if (ret) 207 goto out_disable_irq; 208 209 ret = data->chip_info->ops.read_prox_data(data, chan, &rawval); 210 if (ret) 211 goto out_disable_irq; 212 213 *val = sign_extend32(be16_to_cpu(rawval), chan->scan_type.realbits - 1); 214 215 ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 216 if (ret) 217 goto out_put_channel; 218 219 ret = sx_common_put_read_channel(data, chan->channel); 220 if (ret) 221 goto out; 222 223 mutex_unlock(&data->mutex); 224 225 return IIO_VAL_INT; 226 227out_disable_irq: 228 sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 229out_put_channel: 230 sx_common_put_read_channel(data, chan->channel); 231out: 232 mutex_unlock(&data->mutex); 233 234 return ret; 235} 236EXPORT_SYMBOL_NS_GPL(sx_common_read_proximity, "SEMTECH_PROX"); 237 238/** 239 * sx_common_read_event_config() - Configure event setting. 240 * @indio_dev: iio device object 241 * @chan: Channel to read 242 * @type: Type of event (unused) 243 * @dir: Direction of event (unused) 244 * 245 * return if the given channel is used for event gathering. 246 */ 247int sx_common_read_event_config(struct iio_dev *indio_dev, 248 const struct iio_chan_spec *chan, 249 enum iio_event_type type, 250 enum iio_event_direction dir) 251{ 252 struct sx_common_data *data = iio_priv(indio_dev); 253 254 return !!(data->chan_event & BIT(chan->channel)); 255} 256EXPORT_SYMBOL_NS_GPL(sx_common_read_event_config, "SEMTECH_PROX"); 257 258/** 259 * sx_common_write_event_config() - Configure event setting. 260 * @indio_dev: iio device object 261 * @chan: Channel to enable 262 * @type: Type of event (unused) 263 * @dir: Direction of event (unused) 264 * @state: State of the event. 265 * 266 * Enable/Disable event on a given channel. 267 */ 268int sx_common_write_event_config(struct iio_dev *indio_dev, 269 const struct iio_chan_spec *chan, 270 enum iio_event_type type, 271 enum iio_event_direction dir, bool state) 272{ 273 struct sx_common_data *data = iio_priv(indio_dev); 274 unsigned int eventirq = SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ; 275 int ret; 276 277 /* If the state hasn't changed, there's nothing to do. */ 278 if (!!(data->chan_event & BIT(chan->channel)) == state) 279 return 0; 280 281 mutex_lock(&data->mutex); 282 if (state) { 283 ret = sx_common_get_event_channel(data, chan->channel); 284 if (ret) 285 goto out_unlock; 286 if (!(data->chan_event & ~BIT(chan->channel))) { 287 ret = sx_common_enable_irq(data, eventirq); 288 if (ret) 289 sx_common_put_event_channel(data, chan->channel); 290 } 291 } else { 292 ret = sx_common_put_event_channel(data, chan->channel); 293 if (ret) 294 goto out_unlock; 295 if (!data->chan_event) { 296 ret = sx_common_disable_irq(data, eventirq); 297 if (ret) 298 sx_common_get_event_channel(data, chan->channel); 299 } 300 } 301 302out_unlock: 303 mutex_unlock(&data->mutex); 304 return ret; 305} 306EXPORT_SYMBOL_NS_GPL(sx_common_write_event_config, "SEMTECH_PROX"); 307 308static int sx_common_set_trigger_state(struct iio_trigger *trig, bool state) 309{ 310 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 311 struct sx_common_data *data = iio_priv(indio_dev); 312 int ret = 0; 313 314 mutex_lock(&data->mutex); 315 316 if (state) 317 ret = sx_common_enable_irq(data, SX_COMMON_CONVDONE_IRQ); 318 else if (!data->chan_read) 319 ret = sx_common_disable_irq(data, SX_COMMON_CONVDONE_IRQ); 320 if (ret) 321 goto out; 322 323 data->trigger_enabled = state; 324 325out: 326 mutex_unlock(&data->mutex); 327 328 return ret; 329} 330 331static const struct iio_trigger_ops sx_common_trigger_ops = { 332 .set_trigger_state = sx_common_set_trigger_state, 333}; 334 335static irqreturn_t sx_common_irq_thread_handler(int irq, void *private) 336{ 337 struct iio_dev *indio_dev = private; 338 struct sx_common_data *data = iio_priv(indio_dev); 339 int ret; 340 unsigned int val; 341 342 mutex_lock(&data->mutex); 343 344 ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val); 345 if (ret) { 346 dev_err(&data->client->dev, "i2c transfer error in irq\n"); 347 goto out; 348 } 349 350 if (val & ((SX_COMMON_FAR_IRQ | SX_COMMON_CLOSE_IRQ) << data->chip_info->irq_msk_offset)) 351 sx_common_push_events(indio_dev); 352 353 if (val & (SX_COMMON_CONVDONE_IRQ << data->chip_info->irq_msk_offset)) 354 complete(&data->completion); 355 356out: 357 mutex_unlock(&data->mutex); 358 359 return IRQ_HANDLED; 360} 361 362static irqreturn_t sx_common_trigger_handler(int irq, void *private) 363{ 364 struct iio_poll_func *pf = private; 365 struct iio_dev *indio_dev = pf->indio_dev; 366 struct sx_common_data *data = iio_priv(indio_dev); 367 __be16 val; 368 int bit, ret, i = 0; 369 370 mutex_lock(&data->mutex); 371 372 iio_for_each_active_channel(indio_dev, bit) { 373 ret = data->chip_info->ops.read_prox_data(data, 374 &indio_dev->channels[bit], 375 &val); 376 if (ret) 377 goto out; 378 379 data->buffer.channels[i++] = val; 380 } 381 382 iio_push_to_buffers_with_ts(indio_dev, &data->buffer, 383 sizeof(data->buffer), pf->timestamp); 384 385out: 386 mutex_unlock(&data->mutex); 387 388 iio_trigger_notify_done(indio_dev->trig); 389 390 return IRQ_HANDLED; 391} 392 393static int sx_common_buffer_preenable(struct iio_dev *indio_dev) 394{ 395 struct sx_common_data *data = iio_priv(indio_dev); 396 unsigned long channels = 0; 397 int bit, ret; 398 399 mutex_lock(&data->mutex); 400 iio_for_each_active_channel(indio_dev, bit) 401 __set_bit(indio_dev->channels[bit].channel, &channels); 402 403 ret = sx_common_update_chan_en(data, channels, data->chan_event); 404 mutex_unlock(&data->mutex); 405 return ret; 406} 407 408static int sx_common_buffer_postdisable(struct iio_dev *indio_dev) 409{ 410 struct sx_common_data *data = iio_priv(indio_dev); 411 int ret; 412 413 mutex_lock(&data->mutex); 414 ret = sx_common_update_chan_en(data, 0, data->chan_event); 415 mutex_unlock(&data->mutex); 416 return ret; 417} 418 419static const struct iio_buffer_setup_ops sx_common_buffer_setup_ops = { 420 .preenable = sx_common_buffer_preenable, 421 .postdisable = sx_common_buffer_postdisable, 422}; 423 424#define SX_COMMON_SOFT_RESET 0xde 425 426static int sx_common_init_device(struct device *dev, struct iio_dev *indio_dev) 427{ 428 struct sx_common_data *data = iio_priv(indio_dev); 429 struct sx_common_reg_default tmp; 430 const struct sx_common_reg_default *initval; 431 int ret; 432 unsigned int i, val; 433 434 ret = regmap_write(data->regmap, data->chip_info->reg_reset, 435 SX_COMMON_SOFT_RESET); 436 if (ret) 437 return ret; 438 439 usleep_range(1000, 2000); /* power-up time is ~1ms. */ 440 441 /* Clear reset interrupt state by reading SX_COMMON_REG_IRQ_SRC. */ 442 ret = regmap_read(data->regmap, SX_COMMON_REG_IRQ_SRC, &val); 443 if (ret) 444 return ret; 445 446 /* Program defaults from constant or BIOS. */ 447 for (i = 0; i < data->chip_info->num_default_regs; i++) { 448 initval = data->chip_info->ops.get_default_reg(dev, i, &tmp); 449 ret = regmap_write(data->regmap, initval->reg, initval->def); 450 if (ret) 451 return ret; 452 } 453 454 return data->chip_info->ops.init_compensation(indio_dev); 455} 456 457/** 458 * sx_common_probe() - Common setup for Semtech SAR sensor 459 * @client: I2C client object 460 * @chip_info: Semtech sensor chip information. 461 * @regmap_config: Sensor registers map configuration. 462 */ 463int sx_common_probe(struct i2c_client *client, 464 const struct sx_common_chip_info *chip_info, 465 const struct regmap_config *regmap_config) 466{ 467 static const char * const regulator_names[] = { "vdd", "svdd" }; 468 struct device *dev = &client->dev; 469 struct iio_dev *indio_dev; 470 struct sx_common_data *data; 471 int ret; 472 473 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 474 if (!indio_dev) 475 return -ENOMEM; 476 477 data = iio_priv(indio_dev); 478 479 data->chip_info = chip_info; 480 data->client = client; 481 mutex_init(&data->mutex); 482 init_completion(&data->completion); 483 484 data->regmap = devm_regmap_init_i2c(client, regmap_config); 485 if (IS_ERR(data->regmap)) 486 return dev_err_probe(dev, PTR_ERR(data->regmap), 487 "Could init register map\n"); 488 489 ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulator_names), 490 regulator_names); 491 if (ret) 492 return dev_err_probe(dev, ret, "Unable to get regulators\n"); 493 494 /* Must wait for Tpor time after initial power up */ 495 usleep_range(1000, 1100); 496 497 ret = data->chip_info->ops.check_whoami(dev, indio_dev); 498 if (ret) 499 return dev_err_probe(dev, ret, "error reading WHOAMI\n"); 500 501 indio_dev->modes = INDIO_DIRECT_MODE; 502 503 indio_dev->channels = data->chip_info->iio_channels; 504 indio_dev->num_channels = data->chip_info->num_iio_channels; 505 indio_dev->info = &data->chip_info->iio_info; 506 507 i2c_set_clientdata(client, indio_dev); 508 509 ret = sx_common_init_device(dev, indio_dev); 510 if (ret) 511 return dev_err_probe(dev, ret, "Unable to initialize sensor\n"); 512 513 if (client->irq) { 514 ret = devm_request_threaded_irq(dev, client->irq, 515 sx_common_irq_handler, 516 sx_common_irq_thread_handler, 517 IRQF_ONESHOT, 518 "sx_event", indio_dev); 519 if (ret) 520 return dev_err_probe(dev, ret, "No IRQ\n"); 521 522 data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 523 indio_dev->name, 524 iio_device_id(indio_dev)); 525 if (!data->trig) 526 return -ENOMEM; 527 528 data->trig->ops = &sx_common_trigger_ops; 529 iio_trigger_set_drvdata(data->trig, indio_dev); 530 531 ret = devm_iio_trigger_register(dev, data->trig); 532 if (ret) 533 return ret; 534 } 535 536 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 537 iio_pollfunc_store_time, 538 sx_common_trigger_handler, 539 &sx_common_buffer_setup_ops); 540 if (ret) 541 return ret; 542 543 return devm_iio_device_register(dev, indio_dev); 544} 545EXPORT_SYMBOL_NS_GPL(sx_common_probe, "SEMTECH_PROX"); 546 547MODULE_AUTHOR("Gwendal Grignou <gwendal@chromium.org>"); 548MODULE_DESCRIPTION("Common functions and structures for Semtech sensor"); 549MODULE_LICENSE("GPL v2");
~/
Read-only file preview.