linux/drivers/mfd/iqs62x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Azoteq IQS620A/621/622/624/625 Multi-Function Sensors
   4 *
   5 * Copyright (C) 2019 Jeff LaBundy <jeff@labundy.com>
   6 *
   7 * These devices rely on application-specific register settings and calibration
   8 * data developed in and exported from a suite of GUIs offered by the vendor. A
   9 * separate tool converts the GUIs' ASCII-based output into a standard firmware
  10 * file parsed by the driver.
  11 *
  12 * Link to datasheets and GUIs: https://www.azoteq.com/
  13 *
  14 * Link to conversion tool: https://github.com/jlabundy/iqs62x-h2bin.git
  15 */
  16
  17#include <linux/completion.h>
  18#include <linux/delay.h>
  19#include <linux/device.h>
  20#include <linux/err.h>
  21#include <linux/firmware.h>
  22#include <linux/i2c.h>
  23#include <linux/interrupt.h>
  24#include <linux/kernel.h>
  25#include <linux/list.h>
  26#include <linux/mfd/core.h>
  27#include <linux/mfd/iqs62x.h>
  28#include <linux/module.h>
  29#include <linux/notifier.h>
  30#include <linux/of_device.h>
  31#include <linux/property.h>
  32#include <linux/regmap.h>
  33#include <linux/slab.h>
  34#include <asm/unaligned.h>
  35
  36#define IQS62X_PROD_NUM                         0x00
  37
  38#define IQS62X_SYS_FLAGS                        0x10
  39#define IQS62X_SYS_FLAGS_IN_ATI                 BIT(2)
  40
  41#define IQS620_HALL_FLAGS                       0x16
  42#define IQS621_HALL_FLAGS                       0x19
  43#define IQS622_HALL_FLAGS                       IQS621_HALL_FLAGS
  44
  45#define IQS624_INTERVAL_NUM                     0x18
  46#define IQS625_INTERVAL_NUM                     0x12
  47
  48#define IQS622_PROX_SETTINGS_4                  0x48
  49#define IQS620_PROX_SETTINGS_4                  0x50
  50#define IQS620_PROX_SETTINGS_4_SAR_EN           BIT(7)
  51
  52#define IQS621_ALS_CAL_DIV_LUX                  0x82
  53#define IQS621_ALS_CAL_DIV_IR                   0x83
  54
  55#define IQS620_TEMP_CAL_MULT                    0xC2
  56#define IQS620_TEMP_CAL_DIV                     0xC3
  57#define IQS620_TEMP_CAL_OFFS                    0xC4
  58
  59#define IQS62X_SYS_SETTINGS                     0xD0
  60#define IQS62X_SYS_SETTINGS_SOFT_RESET          BIT(7)
  61#define IQS62X_SYS_SETTINGS_ACK_RESET           BIT(6)
  62#define IQS62X_SYS_SETTINGS_EVENT_MODE          BIT(5)
  63#define IQS62X_SYS_SETTINGS_CLK_DIV             BIT(4)
  64#define IQS62X_SYS_SETTINGS_REDO_ATI            BIT(1)
  65
  66#define IQS62X_PWR_SETTINGS                     0xD2
  67#define IQS62X_PWR_SETTINGS_DIS_AUTO            BIT(5)
  68#define IQS62X_PWR_SETTINGS_PWR_MODE_MASK       (BIT(4) | BIT(3))
  69#define IQS62X_PWR_SETTINGS_PWR_MODE_HALT       (BIT(4) | BIT(3))
  70#define IQS62X_PWR_SETTINGS_PWR_MODE_NORM       0
  71
  72#define IQS62X_OTP_CMD                          0xF0
  73#define IQS62X_OTP_CMD_FG3                      0x13
  74#define IQS62X_OTP_DATA                         0xF1
  75#define IQS62X_MAX_REG                          0xFF
  76
  77#define IQS62X_HALL_CAL_MASK                    GENMASK(3, 0)
  78
  79#define IQS62X_FW_REC_TYPE_INFO                 0
  80#define IQS62X_FW_REC_TYPE_PROD                 1
  81#define IQS62X_FW_REC_TYPE_HALL                 2
  82#define IQS62X_FW_REC_TYPE_MASK                 3
  83#define IQS62X_FW_REC_TYPE_DATA                 4
  84
  85#define IQS62X_ATI_POLL_SLEEP_US                10000
  86#define IQS62X_ATI_POLL_TIMEOUT_US              500000
  87#define IQS62X_ATI_STABLE_DELAY_MS              150
  88
  89struct iqs62x_fw_rec {
  90        u8 type;
  91        u8 addr;
  92        u8 len;
  93        u8 data;
  94} __packed;
  95
  96struct iqs62x_fw_blk {
  97        struct list_head list;
  98        u8 addr;
  99        u8 mask;
 100        u8 len;
 101        u8 data[];
 102};
 103
 104struct iqs62x_info {
 105        u8 prod_num;
 106        u8 sw_num;
 107        u8 hw_num;
 108} __packed;
 109
 110static int iqs62x_dev_init(struct iqs62x_core *iqs62x)
 111{
 112        struct iqs62x_fw_blk *fw_blk;
 113        unsigned int val;
 114        int ret;
 115        u8 clk_div = 1;
 116
 117        list_for_each_entry(fw_blk, &iqs62x->fw_blk_head, list) {
 118                if (fw_blk->mask)
 119                        ret = regmap_update_bits(iqs62x->regmap, fw_blk->addr,
 120                                                 fw_blk->mask, *fw_blk->data);
 121                else
 122                        ret = regmap_raw_write(iqs62x->regmap, fw_blk->addr,
 123                                               fw_blk->data, fw_blk->len);
 124                if (ret)
 125                        return ret;
 126        }
 127
 128        switch (iqs62x->dev_desc->prod_num) {
 129        case IQS620_PROD_NUM:
 130        case IQS622_PROD_NUM:
 131                ret = regmap_read(iqs62x->regmap,
 132                                  iqs62x->dev_desc->prox_settings, &val);
 133                if (ret)
 134                        return ret;
 135
 136                if (val & IQS620_PROX_SETTINGS_4_SAR_EN)
 137                        iqs62x->ui_sel = IQS62X_UI_SAR1;
 138
 139                fallthrough;
 140
 141        case IQS621_PROD_NUM:
 142                ret = regmap_write(iqs62x->regmap, IQS620_GLBL_EVENT_MASK,
 143                                   IQS620_GLBL_EVENT_MASK_PMU |
 144                                   iqs62x->dev_desc->prox_mask |
 145                                   iqs62x->dev_desc->sar_mask |
 146                                   iqs62x->dev_desc->hall_mask |
 147                                   iqs62x->dev_desc->hyst_mask |
 148                                   iqs62x->dev_desc->temp_mask |
 149                                   iqs62x->dev_desc->als_mask |
 150                                   iqs62x->dev_desc->ir_mask);
 151                if (ret)
 152                        return ret;
 153                break;
 154
 155        default:
 156                ret = regmap_write(iqs62x->regmap, IQS624_HALL_UI,
 157                                   IQS624_HALL_UI_WHL_EVENT |
 158                                   IQS624_HALL_UI_INT_EVENT |
 159                                   IQS624_HALL_UI_AUTO_CAL);
 160                if (ret)
 161                        return ret;
 162
 163                /*
 164                 * The IQS625 default interval divider is below the minimum
 165                 * permissible value, and the datasheet mandates that it is
 166                 * corrected during initialization (unless an updated value
 167                 * has already been provided by firmware).
 168                 *
 169                 * To protect against an unacceptably low user-entered value
 170                 * stored in the firmware, the same check is extended to the
 171                 * IQS624 as well.
 172                 */
 173                ret = regmap_read(iqs62x->regmap, IQS624_INTERVAL_DIV, &val);
 174                if (ret)
 175                        return ret;
 176
 177                if (val >= iqs62x->dev_desc->interval_div)
 178                        break;
 179
 180                ret = regmap_write(iqs62x->regmap, IQS624_INTERVAL_DIV,
 181                                   iqs62x->dev_desc->interval_div);
 182                if (ret)
 183                        return ret;
 184        }
 185
 186        ret = regmap_read(iqs62x->regmap, IQS62X_SYS_SETTINGS, &val);
 187        if (ret)
 188                return ret;
 189
 190        if (val & IQS62X_SYS_SETTINGS_CLK_DIV)
 191                clk_div = iqs62x->dev_desc->clk_div;
 192
 193        ret = regmap_write(iqs62x->regmap, IQS62X_SYS_SETTINGS, val |
 194                           IQS62X_SYS_SETTINGS_ACK_RESET |
 195                           IQS62X_SYS_SETTINGS_EVENT_MODE |
 196                           IQS62X_SYS_SETTINGS_REDO_ATI);
 197        if (ret)
 198                return ret;
 199
 200        ret = regmap_read_poll_timeout(iqs62x->regmap, IQS62X_SYS_FLAGS, val,
 201                                       !(val & IQS62X_SYS_FLAGS_IN_ATI),
 202                                       IQS62X_ATI_POLL_SLEEP_US,
 203                                       IQS62X_ATI_POLL_TIMEOUT_US * clk_div);
 204        if (ret)
 205                return ret;
 206
 207        msleep(IQS62X_ATI_STABLE_DELAY_MS * clk_div);
 208
 209        return 0;
 210}
 211
 212static int iqs62x_firmware_parse(struct iqs62x_core *iqs62x,
 213                                 const struct firmware *fw)
 214{
 215        struct i2c_client *client = iqs62x->client;
 216        struct iqs62x_fw_rec *fw_rec;
 217        struct iqs62x_fw_blk *fw_blk;
 218        unsigned int val;
 219        size_t pos = 0;
 220        int ret = 0;
 221        u8 mask, len, *data;
 222        u8 hall_cal_index = 0;
 223
 224        while (pos < fw->size) {
 225                if (pos + sizeof(*fw_rec) > fw->size) {
 226                        ret = -EINVAL;
 227                        break;
 228                }
 229                fw_rec = (struct iqs62x_fw_rec *)(fw->data + pos);
 230                pos += sizeof(*fw_rec);
 231
 232                if (pos + fw_rec->len - 1 > fw->size) {
 233                        ret = -EINVAL;
 234                        break;
 235                }
 236                pos += fw_rec->len - 1;
 237
 238                switch (fw_rec->type) {
 239                case IQS62X_FW_REC_TYPE_INFO:
 240                        continue;
 241
 242                case IQS62X_FW_REC_TYPE_PROD:
 243                        if (fw_rec->data == iqs62x->dev_desc->prod_num)
 244                                continue;
 245
 246                        dev_err(&client->dev,
 247                                "Incompatible product number: 0x%02X\n",
 248                                fw_rec->data);
 249                        ret = -EINVAL;
 250                        break;
 251
 252                case IQS62X_FW_REC_TYPE_HALL:
 253                        if (!hall_cal_index) {
 254                                ret = regmap_write(iqs62x->regmap,
 255                                                   IQS62X_OTP_CMD,
 256                                                   IQS62X_OTP_CMD_FG3);
 257                                if (ret)
 258                                        break;
 259
 260                                ret = regmap_read(iqs62x->regmap,
 261                                                  IQS62X_OTP_DATA, &val);
 262                                if (ret)
 263                                        break;
 264
 265                                hall_cal_index = val & IQS62X_HALL_CAL_MASK;
 266                                if (!hall_cal_index) {
 267                                        dev_err(&client->dev,
 268                                                "Uncalibrated device\n");
 269                                        ret = -ENODATA;
 270                                        break;
 271                                }
 272                        }
 273
 274                        if (hall_cal_index > fw_rec->len) {
 275                                ret = -EINVAL;
 276                                break;
 277                        }
 278
 279                        mask = 0;
 280                        data = &fw_rec->data + hall_cal_index - 1;
 281                        len = sizeof(*data);
 282                        break;
 283
 284                case IQS62X_FW_REC_TYPE_MASK:
 285                        if (fw_rec->len < (sizeof(mask) + sizeof(*data))) {
 286                                ret = -EINVAL;
 287                                break;
 288                        }
 289
 290                        mask = fw_rec->data;
 291                        data = &fw_rec->data + sizeof(mask);
 292                        len = sizeof(*data);
 293                        break;
 294
 295                case IQS62X_FW_REC_TYPE_DATA:
 296                        mask = 0;
 297                        data = &fw_rec->data;
 298                        len = fw_rec->len;
 299                        break;
 300
 301                default:
 302                        dev_err(&client->dev,
 303                                "Unrecognized record type: 0x%02X\n",
 304                                fw_rec->type);
 305                        ret = -EINVAL;
 306                }
 307
 308                if (ret)
 309                        break;
 310
 311                fw_blk = devm_kzalloc(&client->dev,
 312                                      struct_size(fw_blk, data, len),
 313                                      GFP_KERNEL);
 314                if (!fw_blk) {
 315                        ret = -ENOMEM;
 316                        break;
 317                }
 318
 319                fw_blk->addr = fw_rec->addr;
 320                fw_blk->mask = mask;
 321                fw_blk->len = len;
 322                memcpy(fw_blk->data, data, len);
 323
 324                list_add(&fw_blk->list, &iqs62x->fw_blk_head);
 325        }
 326
 327        release_firmware(fw);
 328
 329        return ret;
 330}
 331
 332const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS] = {
 333        [IQS62X_EVENT_PROX_CH0_T] = {
 334                .reg    = IQS62X_EVENT_PROX,
 335                .mask   = BIT(4),
 336                .val    = BIT(4),
 337        },
 338        [IQS62X_EVENT_PROX_CH0_P] = {
 339                .reg    = IQS62X_EVENT_PROX,
 340                .mask   = BIT(0),
 341                .val    = BIT(0),
 342        },
 343        [IQS62X_EVENT_PROX_CH1_T] = {
 344                .reg    = IQS62X_EVENT_PROX,
 345                .mask   = BIT(5),
 346                .val    = BIT(5),
 347        },
 348        [IQS62X_EVENT_PROX_CH1_P] = {
 349                .reg    = IQS62X_EVENT_PROX,
 350                .mask   = BIT(1),
 351                .val    = BIT(1),
 352        },
 353        [IQS62X_EVENT_PROX_CH2_T] = {
 354                .reg    = IQS62X_EVENT_PROX,
 355                .mask   = BIT(6),
 356                .val    = BIT(6),
 357        },
 358        [IQS62X_EVENT_PROX_CH2_P] = {
 359                .reg    = IQS62X_EVENT_PROX,
 360                .mask   = BIT(2),
 361                .val    = BIT(2),
 362        },
 363        [IQS62X_EVENT_HYST_POS_T] = {
 364                .reg    = IQS62X_EVENT_HYST,
 365                .mask   = BIT(6) | BIT(7),
 366                .val    = BIT(6),
 367        },
 368        [IQS62X_EVENT_HYST_POS_P] = {
 369                .reg    = IQS62X_EVENT_HYST,
 370                .mask   = BIT(5) | BIT(7),
 371                .val    = BIT(5),
 372        },
 373        [IQS62X_EVENT_HYST_NEG_T] = {
 374                .reg    = IQS62X_EVENT_HYST,
 375                .mask   = BIT(6) | BIT(7),
 376                .val    = BIT(6) | BIT(7),
 377        },
 378        [IQS62X_EVENT_HYST_NEG_P] = {
 379                .reg    = IQS62X_EVENT_HYST,
 380                .mask   = BIT(5) | BIT(7),
 381                .val    = BIT(5) | BIT(7),
 382        },
 383        [IQS62X_EVENT_SAR1_ACT] = {
 384                .reg    = IQS62X_EVENT_HYST,
 385                .mask   = BIT(4),
 386                .val    = BIT(4),
 387        },
 388        [IQS62X_EVENT_SAR1_QRD] = {
 389                .reg    = IQS62X_EVENT_HYST,
 390                .mask   = BIT(2),
 391                .val    = BIT(2),
 392        },
 393        [IQS62X_EVENT_SAR1_MOVE] = {
 394                .reg    = IQS62X_EVENT_HYST,
 395                .mask   = BIT(1),
 396                .val    = BIT(1),
 397        },
 398        [IQS62X_EVENT_SAR1_HALT] = {
 399                .reg    = IQS62X_EVENT_HYST,
 400                .mask   = BIT(0),
 401                .val    = BIT(0),
 402        },
 403        [IQS62X_EVENT_WHEEL_UP] = {
 404                .reg    = IQS62X_EVENT_WHEEL,
 405                .mask   = BIT(7) | BIT(6),
 406                .val    = BIT(7),
 407        },
 408        [IQS62X_EVENT_WHEEL_DN] = {
 409                .reg    = IQS62X_EVENT_WHEEL,
 410                .mask   = BIT(7) | BIT(6),
 411                .val    = BIT(7) | BIT(6),
 412        },
 413        [IQS62X_EVENT_HALL_N_T] = {
 414                .reg    = IQS62X_EVENT_HALL,
 415                .mask   = BIT(2) | BIT(0),
 416                .val    = BIT(2),
 417        },
 418        [IQS62X_EVENT_HALL_N_P] = {
 419                .reg    = IQS62X_EVENT_HALL,
 420                .mask   = BIT(1) | BIT(0),
 421                .val    = BIT(1),
 422        },
 423        [IQS62X_EVENT_HALL_S_T] = {
 424                .reg    = IQS62X_EVENT_HALL,
 425                .mask   = BIT(2) | BIT(0),
 426                .val    = BIT(2) | BIT(0),
 427        },
 428        [IQS62X_EVENT_HALL_S_P] = {
 429                .reg    = IQS62X_EVENT_HALL,
 430                .mask   = BIT(1) | BIT(0),
 431                .val    = BIT(1) | BIT(0),
 432        },
 433        [IQS62X_EVENT_SYS_RESET] = {
 434                .reg    = IQS62X_EVENT_SYS,
 435                .mask   = BIT(7),
 436                .val    = BIT(7),
 437        },
 438};
 439EXPORT_SYMBOL_GPL(iqs62x_events);
 440
 441static irqreturn_t iqs62x_irq(int irq, void *context)
 442{
 443        struct iqs62x_core *iqs62x = context;
 444        struct i2c_client *client = iqs62x->client;
 445        struct iqs62x_event_data event_data;
 446        struct iqs62x_event_desc event_desc;
 447        enum iqs62x_event_reg event_reg;
 448        unsigned long event_flags = 0;
 449        int ret, i, j;
 450        u8 event_map[IQS62X_EVENT_SIZE];
 451
 452        /*
 453         * The device asserts the RDY output to signal the beginning of a
 454         * communication window, which is closed by an I2C stop condition.
 455         * As such, all interrupt status is captured in a single read and
 456         * broadcast to any interested sub-device drivers.
 457         */
 458        ret = regmap_raw_read(iqs62x->regmap, IQS62X_SYS_FLAGS, event_map,
 459                              sizeof(event_map));
 460        if (ret) {
 461                dev_err(&client->dev, "Failed to read device status: %d\n",
 462                        ret);
 463                return IRQ_NONE;
 464        }
 465
 466        for (i = 0; i < sizeof(event_map); i++) {
 467                event_reg = iqs62x->dev_desc->event_regs[iqs62x->ui_sel][i];
 468
 469                switch (event_reg) {
 470                case IQS62X_EVENT_UI_LO:
 471                        event_data.ui_data = get_unaligned_le16(&event_map[i]);
 472
 473                        fallthrough;
 474
 475                case IQS62X_EVENT_UI_HI:
 476                case IQS62X_EVENT_NONE:
 477                        continue;
 478
 479                case IQS62X_EVENT_ALS:
 480                        event_data.als_flags = event_map[i];
 481                        continue;
 482
 483                case IQS62X_EVENT_IR:
 484                        event_data.ir_flags = event_map[i];
 485                        continue;
 486
 487                case IQS62X_EVENT_INTER:
 488                        event_data.interval = event_map[i];
 489                        continue;
 490
 491                case IQS62X_EVENT_HYST:
 492                        event_map[i] <<= iqs62x->dev_desc->hyst_shift;
 493
 494                        fallthrough;
 495
 496                case IQS62X_EVENT_WHEEL:
 497                case IQS62X_EVENT_HALL:
 498                case IQS62X_EVENT_PROX:
 499                case IQS62X_EVENT_SYS:
 500                        break;
 501                }
 502
 503                for (j = 0; j < IQS62X_NUM_EVENTS; j++) {
 504                        event_desc = iqs62x_events[j];
 505
 506                        if (event_desc.reg != event_reg)
 507                                continue;
 508
 509                        if ((event_map[i] & event_desc.mask) == event_desc.val)
 510                                event_flags |= BIT(j);
 511                }
 512        }
 513
 514        /*
 515         * The device resets itself in response to the I2C master stalling
 516         * communication past a fixed timeout. In this case, all registers
 517         * are restored and any interested sub-device drivers are notified.
 518         */
 519        if (event_flags & BIT(IQS62X_EVENT_SYS_RESET)) {
 520                dev_err(&client->dev, "Unexpected device reset\n");
 521
 522                ret = iqs62x_dev_init(iqs62x);
 523                if (ret) {
 524                        dev_err(&client->dev,
 525                                "Failed to re-initialize device: %d\n", ret);
 526                        return IRQ_NONE;
 527                }
 528        }
 529
 530        ret = blocking_notifier_call_chain(&iqs62x->nh, event_flags,
 531                                           &event_data);
 532        if (ret & NOTIFY_STOP_MASK)
 533                return IRQ_NONE;
 534
 535        /*
 536         * Once the communication window is closed, a small delay is added to
 537         * ensure the device's RDY output has been deasserted by the time the
 538         * interrupt handler returns.
 539         */
 540        usleep_range(50, 100);
 541
 542        return IRQ_HANDLED;
 543}
 544
 545static void iqs62x_firmware_load(const struct firmware *fw, void *context)
 546{
 547        struct iqs62x_core *iqs62x = context;
 548        struct i2c_client *client = iqs62x->client;
 549        int ret;
 550
 551        if (fw) {
 552                ret = iqs62x_firmware_parse(iqs62x, fw);
 553                if (ret) {
 554                        dev_err(&client->dev, "Failed to parse firmware: %d\n",
 555                                ret);
 556                        goto err_out;
 557                }
 558        }
 559
 560        ret = iqs62x_dev_init(iqs62x);
 561        if (ret) {
 562                dev_err(&client->dev, "Failed to initialize device: %d\n", ret);
 563                goto err_out;
 564        }
 565
 566        ret = devm_request_threaded_irq(&client->dev, client->irq,
 567                                        NULL, iqs62x_irq, IRQF_ONESHOT,
 568                                        client->name, iqs62x);
 569        if (ret) {
 570                dev_err(&client->dev, "Failed to request IRQ: %d\n", ret);
 571                goto err_out;
 572        }
 573
 574        ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
 575                                   iqs62x->dev_desc->sub_devs,
 576                                   iqs62x->dev_desc->num_sub_devs,
 577                                   NULL, 0, NULL);
 578        if (ret)
 579                dev_err(&client->dev, "Failed to add sub-devices: %d\n", ret);
 580
 581err_out:
 582        complete_all(&iqs62x->fw_done);
 583}
 584
 585static const struct mfd_cell iqs620at_sub_devs[] = {
 586        {
 587                .name = "iqs62x-keys",
 588                .of_compatible = "azoteq,iqs620a-keys",
 589        },
 590        {
 591                .name = "iqs620a-pwm",
 592                .of_compatible = "azoteq,iqs620a-pwm",
 593        },
 594        { .name = "iqs620at-temp", },
 595};
 596
 597static const struct mfd_cell iqs620a_sub_devs[] = {
 598        {
 599                .name = "iqs62x-keys",
 600                .of_compatible = "azoteq,iqs620a-keys",
 601        },
 602        {
 603                .name = "iqs620a-pwm",
 604                .of_compatible = "azoteq,iqs620a-pwm",
 605        },
 606};
 607
 608static const struct mfd_cell iqs621_sub_devs[] = {
 609        {
 610                .name = "iqs62x-keys",
 611                .of_compatible = "azoteq,iqs621-keys",
 612        },
 613        { .name = "iqs621-als", },
 614};
 615
 616static const struct mfd_cell iqs622_sub_devs[] = {
 617        {
 618                .name = "iqs62x-keys",
 619                .of_compatible = "azoteq,iqs622-keys",
 620        },
 621        { .name = "iqs621-als", },
 622};
 623
 624static const struct mfd_cell iqs624_sub_devs[] = {
 625        {
 626                .name = "iqs62x-keys",
 627                .of_compatible = "azoteq,iqs624-keys",
 628        },
 629        { .name = "iqs624-pos", },
 630};
 631
 632static const struct mfd_cell iqs625_sub_devs[] = {
 633        {
 634                .name = "iqs62x-keys",
 635                .of_compatible = "azoteq,iqs625-keys",
 636        },
 637        { .name = "iqs624-pos", },
 638};
 639
 640static const u8 iqs620at_cal_regs[] = {
 641        IQS620_TEMP_CAL_MULT,
 642        IQS620_TEMP_CAL_DIV,
 643        IQS620_TEMP_CAL_OFFS,
 644};
 645
 646static const u8 iqs621_cal_regs[] = {
 647        IQS621_ALS_CAL_DIV_LUX,
 648        IQS621_ALS_CAL_DIV_IR,
 649};
 650
 651static const enum iqs62x_event_reg iqs620a_event_regs[][IQS62X_EVENT_SIZE] = {
 652        [IQS62X_UI_PROX] = {
 653                IQS62X_EVENT_SYS,       /* 0x10 */
 654                IQS62X_EVENT_NONE,
 655                IQS62X_EVENT_PROX,      /* 0x12 */
 656                IQS62X_EVENT_HYST,      /* 0x13 */
 657                IQS62X_EVENT_NONE,
 658                IQS62X_EVENT_NONE,
 659                IQS62X_EVENT_HALL,      /* 0x16 */
 660                IQS62X_EVENT_NONE,
 661                IQS62X_EVENT_NONE,
 662                IQS62X_EVENT_NONE,
 663        },
 664        [IQS62X_UI_SAR1] = {
 665                IQS62X_EVENT_SYS,       /* 0x10 */
 666                IQS62X_EVENT_NONE,
 667                IQS62X_EVENT_NONE,
 668                IQS62X_EVENT_HYST,      /* 0x13 */
 669                IQS62X_EVENT_NONE,
 670                IQS62X_EVENT_NONE,
 671                IQS62X_EVENT_HALL,      /* 0x16 */
 672                IQS62X_EVENT_NONE,
 673                IQS62X_EVENT_NONE,
 674                IQS62X_EVENT_NONE,
 675        },
 676};
 677
 678static const enum iqs62x_event_reg iqs621_event_regs[][IQS62X_EVENT_SIZE] = {
 679        [IQS62X_UI_PROX] = {
 680                IQS62X_EVENT_SYS,       /* 0x10 */
 681                IQS62X_EVENT_NONE,
 682                IQS62X_EVENT_PROX,      /* 0x12 */
 683                IQS62X_EVENT_HYST,      /* 0x13 */
 684                IQS62X_EVENT_NONE,
 685                IQS62X_EVENT_NONE,
 686                IQS62X_EVENT_ALS,       /* 0x16 */
 687                IQS62X_EVENT_UI_LO,     /* 0x17 */
 688                IQS62X_EVENT_UI_HI,     /* 0x18 */
 689                IQS62X_EVENT_HALL,      /* 0x19 */
 690        },
 691};
 692
 693static const enum iqs62x_event_reg iqs622_event_regs[][IQS62X_EVENT_SIZE] = {
 694        [IQS62X_UI_PROX] = {
 695                IQS62X_EVENT_SYS,       /* 0x10 */
 696                IQS62X_EVENT_NONE,
 697                IQS62X_EVENT_PROX,      /* 0x12 */
 698                IQS62X_EVENT_NONE,
 699                IQS62X_EVENT_ALS,       /* 0x14 */
 700                IQS62X_EVENT_NONE,
 701                IQS62X_EVENT_IR,        /* 0x16 */
 702                IQS62X_EVENT_UI_LO,     /* 0x17 */
 703                IQS62X_EVENT_UI_HI,     /* 0x18 */
 704                IQS62X_EVENT_HALL,      /* 0x19 */
 705        },
 706        [IQS62X_UI_SAR1] = {
 707                IQS62X_EVENT_SYS,       /* 0x10 */
 708                IQS62X_EVENT_NONE,
 709                IQS62X_EVENT_NONE,
 710                IQS62X_EVENT_HYST,      /* 0x13 */
 711                IQS62X_EVENT_ALS,       /* 0x14 */
 712                IQS62X_EVENT_NONE,
 713                IQS62X_EVENT_IR,        /* 0x16 */
 714                IQS62X_EVENT_UI_LO,     /* 0x17 */
 715                IQS62X_EVENT_UI_HI,     /* 0x18 */
 716                IQS62X_EVENT_HALL,      /* 0x19 */
 717        },
 718};
 719
 720static const enum iqs62x_event_reg iqs624_event_regs[][IQS62X_EVENT_SIZE] = {
 721        [IQS62X_UI_PROX] = {
 722                IQS62X_EVENT_SYS,       /* 0x10 */
 723                IQS62X_EVENT_NONE,
 724                IQS62X_EVENT_PROX,      /* 0x12 */
 725                IQS62X_EVENT_NONE,
 726                IQS62X_EVENT_WHEEL,     /* 0x14 */
 727                IQS62X_EVENT_NONE,
 728                IQS62X_EVENT_UI_LO,     /* 0x16 */
 729                IQS62X_EVENT_UI_HI,     /* 0x17 */
 730                IQS62X_EVENT_INTER,     /* 0x18 */
 731                IQS62X_EVENT_NONE,
 732        },
 733};
 734
 735static const enum iqs62x_event_reg iqs625_event_regs[][IQS62X_EVENT_SIZE] = {
 736        [IQS62X_UI_PROX] = {
 737                IQS62X_EVENT_SYS,       /* 0x10 */
 738                IQS62X_EVENT_PROX,      /* 0x11 */
 739                IQS62X_EVENT_INTER,     /* 0x12 */
 740                IQS62X_EVENT_NONE,
 741                IQS62X_EVENT_NONE,
 742                IQS62X_EVENT_NONE,
 743                IQS62X_EVENT_NONE,
 744                IQS62X_EVENT_NONE,
 745                IQS62X_EVENT_NONE,
 746                IQS62X_EVENT_NONE,
 747        },
 748};
 749
 750static const struct iqs62x_dev_desc iqs62x_devs[] = {
 751        {
 752                .dev_name       = "iqs620at",
 753                .sub_devs       = iqs620at_sub_devs,
 754                .num_sub_devs   = ARRAY_SIZE(iqs620at_sub_devs),
 755
 756                .prod_num       = IQS620_PROD_NUM,
 757                .sw_num         = 0x08,
 758                .cal_regs       = iqs620at_cal_regs,
 759                .num_cal_regs   = ARRAY_SIZE(iqs620at_cal_regs),
 760
 761                .prox_mask      = BIT(0),
 762                .sar_mask       = BIT(1) | BIT(7),
 763                .hall_mask      = BIT(2),
 764                .hyst_mask      = BIT(3),
 765                .temp_mask      = BIT(4),
 766
 767                .prox_settings  = IQS620_PROX_SETTINGS_4,
 768                .hall_flags     = IQS620_HALL_FLAGS,
 769
 770                .clk_div        = 4,
 771                .fw_name        = "iqs620a.bin",
 772                .event_regs     = &iqs620a_event_regs[IQS62X_UI_PROX],
 773        },
 774        {
 775                .dev_name       = "iqs620a",
 776                .sub_devs       = iqs620a_sub_devs,
 777                .num_sub_devs   = ARRAY_SIZE(iqs620a_sub_devs),
 778
 779                .prod_num       = IQS620_PROD_NUM,
 780                .sw_num         = 0x08,
 781
 782                .prox_mask      = BIT(0),
 783                .sar_mask       = BIT(1) | BIT(7),
 784                .hall_mask      = BIT(2),
 785                .hyst_mask      = BIT(3),
 786                .temp_mask      = BIT(4),
 787
 788                .prox_settings  = IQS620_PROX_SETTINGS_4,
 789                .hall_flags     = IQS620_HALL_FLAGS,
 790
 791                .clk_div        = 4,
 792                .fw_name        = "iqs620a.bin",
 793                .event_regs     = &iqs620a_event_regs[IQS62X_UI_PROX],
 794        },
 795        {
 796                .dev_name       = "iqs621",
 797                .sub_devs       = iqs621_sub_devs,
 798                .num_sub_devs   = ARRAY_SIZE(iqs621_sub_devs),
 799
 800                .prod_num       = IQS621_PROD_NUM,
 801                .sw_num         = 0x09,
 802                .cal_regs       = iqs621_cal_regs,
 803                .num_cal_regs   = ARRAY_SIZE(iqs621_cal_regs),
 804
 805                .prox_mask      = BIT(0),
 806                .hall_mask      = BIT(1),
 807                .als_mask       = BIT(2),
 808                .hyst_mask      = BIT(3),
 809                .temp_mask      = BIT(4),
 810
 811                .als_flags      = IQS621_ALS_FLAGS,
 812                .hall_flags     = IQS621_HALL_FLAGS,
 813                .hyst_shift     = 5,
 814
 815                .clk_div        = 2,
 816                .fw_name        = "iqs621.bin",
 817                .event_regs     = &iqs621_event_regs[IQS62X_UI_PROX],
 818        },
 819        {
 820                .dev_name       = "iqs622",
 821                .sub_devs       = iqs622_sub_devs,
 822                .num_sub_devs   = ARRAY_SIZE(iqs622_sub_devs),
 823
 824                .prod_num       = IQS622_PROD_NUM,
 825                .sw_num         = 0x06,
 826
 827                .prox_mask      = BIT(0),
 828                .sar_mask       = BIT(1),
 829                .hall_mask      = BIT(2),
 830                .als_mask       = BIT(3),
 831                .ir_mask        = BIT(4),
 832
 833                .prox_settings  = IQS622_PROX_SETTINGS_4,
 834                .als_flags      = IQS622_ALS_FLAGS,
 835                .hall_flags     = IQS622_HALL_FLAGS,
 836
 837                .clk_div        = 2,
 838                .fw_name        = "iqs622.bin",
 839                .event_regs     = &iqs622_event_regs[IQS62X_UI_PROX],
 840        },
 841        {
 842                .dev_name       = "iqs624",
 843                .sub_devs       = iqs624_sub_devs,
 844                .num_sub_devs   = ARRAY_SIZE(iqs624_sub_devs),
 845
 846                .prod_num       = IQS624_PROD_NUM,
 847                .sw_num         = 0x0B,
 848
 849                .interval       = IQS624_INTERVAL_NUM,
 850                .interval_div   = 3,
 851
 852                .clk_div        = 2,
 853                .fw_name        = "iqs624.bin",
 854                .event_regs     = &iqs624_event_regs[IQS62X_UI_PROX],
 855        },
 856        {
 857                .dev_name       = "iqs625",
 858                .sub_devs       = iqs625_sub_devs,
 859                .num_sub_devs   = ARRAY_SIZE(iqs625_sub_devs),
 860
 861                .prod_num       = IQS625_PROD_NUM,
 862                .sw_num         = 0x0B,
 863
 864                .interval       = IQS625_INTERVAL_NUM,
 865                .interval_div   = 10,
 866
 867                .clk_div        = 2,
 868                .fw_name        = "iqs625.bin",
 869                .event_regs     = &iqs625_event_regs[IQS62X_UI_PROX],
 870        },
 871};
 872
 873static const struct regmap_config iqs62x_map_config = {
 874        .reg_bits = 8,
 875        .val_bits = 8,
 876        .max_register = IQS62X_MAX_REG,
 877};
 878
 879static int iqs62x_probe(struct i2c_client *client)
 880{
 881        struct iqs62x_core *iqs62x;
 882        struct iqs62x_info info;
 883        unsigned int val;
 884        int ret, i, j;
 885        u8 sw_num = 0;
 886        const char *fw_name = NULL;
 887
 888        iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL);
 889        if (!iqs62x)
 890                return -ENOMEM;
 891
 892        i2c_set_clientdata(client, iqs62x);
 893        iqs62x->client = client;
 894
 895        BLOCKING_INIT_NOTIFIER_HEAD(&iqs62x->nh);
 896        INIT_LIST_HEAD(&iqs62x->fw_blk_head);
 897        init_completion(&iqs62x->fw_done);
 898
 899        iqs62x->regmap = devm_regmap_init_i2c(client, &iqs62x_map_config);
 900        if (IS_ERR(iqs62x->regmap)) {
 901                ret = PTR_ERR(iqs62x->regmap);
 902                dev_err(&client->dev, "Failed to initialize register map: %d\n",
 903                        ret);
 904                return ret;
 905        }
 906
 907        ret = regmap_raw_read(iqs62x->regmap, IQS62X_PROD_NUM, &info,
 908                              sizeof(info));
 909        if (ret)
 910                return ret;
 911
 912        /*
 913         * The following sequence validates the device's product and software
 914         * numbers. It then determines if the device is factory-calibrated by
 915         * checking for nonzero values in the device's designated calibration
 916         * registers (if applicable). Depending on the device, the absence of
 917         * calibration data indicates a reduced feature set or invalid device.
 918         *
 919         * For devices given in both calibrated and uncalibrated versions, the
 920         * calibrated version (e.g. IQS620AT) appears first in the iqs62x_devs
 921         * array. The uncalibrated version (e.g. IQS620A) appears next and has
 922         * the same product and software numbers, but no calibration registers
 923         * are specified.
 924         */
 925        for (i = 0; i < ARRAY_SIZE(iqs62x_devs); i++) {
 926                if (info.prod_num != iqs62x_devs[i].prod_num)
 927                        continue;
 928
 929                iqs62x->dev_desc = &iqs62x_devs[i];
 930
 931                if (info.sw_num < iqs62x->dev_desc->sw_num)
 932                        continue;
 933
 934                sw_num = info.sw_num;
 935
 936                /*
 937                 * Read each of the device's designated calibration registers,
 938                 * if any, and exit from the inner loop early if any are equal
 939                 * to zero (indicating the device is uncalibrated). This could
 940                 * be acceptable depending on the device (e.g. IQS620A instead
 941                 * of IQS620AT).
 942                 */
 943                for (j = 0; j < iqs62x->dev_desc->num_cal_regs; j++) {
 944                        ret = regmap_read(iqs62x->regmap,
 945                                          iqs62x->dev_desc->cal_regs[j], &val);
 946                        if (ret)
 947                                return ret;
 948
 949                        if (!val)
 950                                break;
 951                }
 952
 953                /*
 954                 * If the number of nonzero values read from the device equals
 955                 * the number of designated calibration registers (which could
 956                 * be zero), exit from the outer loop early to signal that the
 957                 * device's product and software numbers match a known device,
 958                 * and the device is calibrated (if applicable).
 959                 */
 960                if (j == iqs62x->dev_desc->num_cal_regs)
 961                        break;
 962        }
 963
 964        if (!iqs62x->dev_desc) {
 965                dev_err(&client->dev, "Unrecognized product number: 0x%02X\n",
 966                        info.prod_num);
 967                return -EINVAL;
 968        }
 969
 970        if (!sw_num) {
 971                dev_err(&client->dev, "Unrecognized software number: 0x%02X\n",
 972                        info.sw_num);
 973                return -EINVAL;
 974        }
 975
 976        if (i == ARRAY_SIZE(iqs62x_devs)) {
 977                dev_err(&client->dev, "Uncalibrated device\n");
 978                return -ENODATA;
 979        }
 980
 981        device_property_read_string(&client->dev, "firmware-name", &fw_name);
 982
 983        ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
 984                                      fw_name ? : iqs62x->dev_desc->fw_name,
 985                                      &client->dev, GFP_KERNEL, iqs62x,
 986                                      iqs62x_firmware_load);
 987        if (ret)
 988                dev_err(&client->dev, "Failed to request firmware: %d\n", ret);
 989
 990        return ret;
 991}
 992
 993static int iqs62x_remove(struct i2c_client *client)
 994{
 995        struct iqs62x_core *iqs62x = i2c_get_clientdata(client);
 996
 997        wait_for_completion(&iqs62x->fw_done);
 998
 999        return 0;
1000}
1001
1002static int __maybe_unused iqs62x_suspend(struct device *dev)
1003{
1004        struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1005        int ret;
1006
1007        wait_for_completion(&iqs62x->fw_done);
1008
1009        /*
1010         * As per the datasheet, automatic mode switching must be disabled
1011         * before the device is placed in or taken out of halt mode.
1012         */
1013        ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1014                                 IQS62X_PWR_SETTINGS_DIS_AUTO, 0xFF);
1015        if (ret)
1016                return ret;
1017
1018        return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1019                                  IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1020                                  IQS62X_PWR_SETTINGS_PWR_MODE_HALT);
1021}
1022
1023static int __maybe_unused iqs62x_resume(struct device *dev)
1024{
1025        struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
1026        int ret;
1027
1028        ret = regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1029                                 IQS62X_PWR_SETTINGS_PWR_MODE_MASK,
1030                                 IQS62X_PWR_SETTINGS_PWR_MODE_NORM);
1031        if (ret)
1032                return ret;
1033
1034        return regmap_update_bits(iqs62x->regmap, IQS62X_PWR_SETTINGS,
1035                                  IQS62X_PWR_SETTINGS_DIS_AUTO, 0);
1036}
1037
1038static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume);
1039
1040static const struct of_device_id iqs62x_of_match[] = {
1041        { .compatible = "azoteq,iqs620a" },
1042        { .compatible = "azoteq,iqs621" },
1043        { .compatible = "azoteq,iqs622" },
1044        { .compatible = "azoteq,iqs624" },
1045        { .compatible = "azoteq,iqs625" },
1046        { }
1047};
1048MODULE_DEVICE_TABLE(of, iqs62x_of_match);
1049
1050static struct i2c_driver iqs62x_i2c_driver = {
1051        .driver = {
1052                .name = "iqs62x",
1053                .of_match_table = iqs62x_of_match,
1054                .pm = &iqs62x_pm,
1055        },
1056        .probe_new = iqs62x_probe,
1057        .remove = iqs62x_remove,
1058};
1059module_i2c_driver(iqs62x_i2c_driver);
1060
1061MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
1062MODULE_DESCRIPTION("Azoteq IQS620A/621/622/624/625 Multi-Function Sensors");
1063MODULE_LICENSE("GPL");
1064