linux/drivers/iio/common/ssp_sensors/ssp_dev.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
   4 */
   5
   6#include <linux/iio/iio.h>
   7#include <linux/interrupt.h>
   8#include <linux/io.h>
   9#include <linux/mfd/core.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/of_gpio.h>
  13#include <linux/of_platform.h>
  14#include "ssp.h"
  15
  16#define SSP_WDT_TIME                    10000
  17#define SSP_LIMIT_RESET_CNT             20
  18#define SSP_LIMIT_TIMEOUT_CNT           3
  19
  20/* It is possible that it is max clk rate for version 1.0 of bootcode */
  21#define SSP_BOOT_SPI_HZ 400000
  22
  23/*
  24 * These fields can look enigmatic but this structure is used mainly to flat
  25 * some values and depends on command type.
  26 */
  27struct ssp_instruction {
  28        __le32 a;
  29        __le32 b;
  30        u8 c;
  31} __attribute__((__packed__));
  32
  33static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
  34        208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
  35        243, 13, 45, 250};
  36
  37static const struct ssp_sensorhub_info ssp_rinato_info = {
  38        .fw_name = "ssp_B2.fw",
  39        .fw_crashed_name = "ssp_crashed.fw",
  40        .fw_rev = 14052300,
  41        .mag_table = ssp_magnitude_table,
  42        .mag_length = ARRAY_SIZE(ssp_magnitude_table),
  43};
  44
  45static const struct ssp_sensorhub_info ssp_thermostat_info = {
  46        .fw_name = "thermostat_B2.fw",
  47        .fw_crashed_name = "ssp_crashed.fw",
  48        .fw_rev = 14080600,
  49        .mag_table = ssp_magnitude_table,
  50        .mag_length = ARRAY_SIZE(ssp_magnitude_table),
  51};
  52
  53static const struct mfd_cell sensorhub_sensor_devs[] = {
  54        {
  55                .name = "ssp-accelerometer",
  56        },
  57        {
  58                .name = "ssp-gyroscope",
  59        },
  60};
  61
  62static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
  63{
  64        gpio_set_value(data->mcu_reset_gpio, 0);
  65        usleep_range(1000, 1200);
  66        gpio_set_value(data->mcu_reset_gpio, 1);
  67        msleep(50);
  68}
  69
  70static void ssp_sync_available_sensors(struct ssp_data *data)
  71{
  72        int i, ret;
  73
  74        for (i = 0; i < SSP_SENSOR_MAX; ++i) {
  75                if (data->available_sensors & BIT(i)) {
  76                        ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
  77                        if (ret < 0) {
  78                                dev_err(&data->spi->dev,
  79                                        "Sync sensor nr: %d fail\n", i);
  80                                continue;
  81                        }
  82                }
  83        }
  84
  85        ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
  86                          data->mcu_dump_mode);
  87        if (ret < 0)
  88                dev_err(&data->spi->dev,
  89                        "SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
  90}
  91
  92static void ssp_enable_mcu(struct ssp_data *data, bool enable)
  93{
  94        dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
  95                 data->shut_down);
  96
  97        if (enable && data->shut_down) {
  98                data->shut_down = false;
  99                enable_irq(data->spi->irq);
 100                enable_irq_wake(data->spi->irq);
 101        } else if (!enable && !data->shut_down) {
 102                data->shut_down = true;
 103                disable_irq(data->spi->irq);
 104                disable_irq_wake(data->spi->irq);
 105        } else {
 106                dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
 107                         enable, data->shut_down);
 108        }
 109}
 110
 111/*
 112 * This function is the first one which communicates with the mcu so it is
 113 * possible that the first attempt will fail
 114 */
 115static int ssp_check_fwbl(struct ssp_data *data)
 116{
 117        int retries = 0;
 118
 119        while (retries++ < 5) {
 120                data->cur_firm_rev = ssp_get_firmware_rev(data);
 121                if (data->cur_firm_rev == SSP_INVALID_REVISION ||
 122                    data->cur_firm_rev == SSP_INVALID_REVISION2) {
 123                        dev_warn(&data->spi->dev,
 124                                 "Invalid revision, trying %d time\n", retries);
 125                } else {
 126                        break;
 127                }
 128        }
 129
 130        if (data->cur_firm_rev == SSP_INVALID_REVISION ||
 131            data->cur_firm_rev == SSP_INVALID_REVISION2) {
 132                dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
 133                return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
 134        }
 135
 136        dev_info(&data->spi->dev,
 137                 "MCU Firm Rev : Old = %8u, New = %8u\n",
 138                 data->cur_firm_rev,
 139                 data->sensorhub_info->fw_rev);
 140
 141        if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
 142                return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
 143
 144        return SSP_FW_DL_STATE_NONE;
 145}
 146
 147static void ssp_reset_mcu(struct ssp_data *data)
 148{
 149        ssp_enable_mcu(data, false);
 150        ssp_clean_pending_list(data);
 151        ssp_toggle_mcu_reset_gpio(data);
 152        ssp_enable_mcu(data, true);
 153}
 154
 155static void ssp_wdt_work_func(struct work_struct *work)
 156{
 157        struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
 158
 159        dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
 160                __func__, data->available_sensors, data->reset_cnt,
 161                data->com_fail_cnt);
 162
 163        ssp_reset_mcu(data);
 164        data->com_fail_cnt = 0;
 165        data->timeout_cnt = 0;
 166}
 167
 168static void ssp_wdt_timer_func(struct timer_list *t)
 169{
 170        struct ssp_data *data = from_timer(data, t, wdt_timer);
 171
 172        switch (data->fw_dl_state) {
 173        case SSP_FW_DL_STATE_FAIL:
 174        case SSP_FW_DL_STATE_DOWNLOADING:
 175        case SSP_FW_DL_STATE_SYNC:
 176                goto _mod;
 177        }
 178
 179        if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
 180            data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
 181                queue_work(system_power_efficient_wq, &data->work_wdt);
 182_mod:
 183        mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
 184}
 185
 186static void ssp_enable_wdt_timer(struct ssp_data *data)
 187{
 188        mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
 189}
 190
 191static void ssp_disable_wdt_timer(struct ssp_data *data)
 192{
 193        del_timer_sync(&data->wdt_timer);
 194        cancel_work_sync(&data->work_wdt);
 195}
 196
 197/**
 198 * ssp_get_sensor_delay() - gets sensor data acquisition period
 199 * @data:       sensorhub structure
 200 * @type:       SSP sensor type
 201 *
 202 * Returns acquisition period in ms
 203 */
 204u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
 205{
 206        return data->delay_buf[type];
 207}
 208EXPORT_SYMBOL(ssp_get_sensor_delay);
 209
 210/**
 211 * ssp_enable_sensor() - enables data acquisition for sensor
 212 * @data:       sensorhub structure
 213 * @type:       SSP sensor type
 214 * @delay:      delay in ms
 215 *
 216 * Returns 0 or negative value in case of error
 217 */
 218int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
 219                      u32 delay)
 220{
 221        int ret;
 222        struct ssp_instruction to_send;
 223
 224        to_send.a = cpu_to_le32(delay);
 225        to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
 226        to_send.c = data->batch_opt_buf[type];
 227
 228        switch (data->check_status[type]) {
 229        case SSP_INITIALIZATION_STATE:
 230                /* do calibration step, now just enable */
 231        case SSP_ADD_SENSOR_STATE:
 232                ret = ssp_send_instruction(data,
 233                                           SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
 234                                           type,
 235                                           (u8 *)&to_send, sizeof(to_send));
 236                if (ret < 0) {
 237                        dev_err(&data->spi->dev, "Enabling sensor failed\n");
 238                        data->check_status[type] = SSP_NO_SENSOR_STATE;
 239                        goto derror;
 240                }
 241
 242                data->sensor_enable |= BIT(type);
 243                data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
 244                break;
 245        case SSP_RUNNING_SENSOR_STATE:
 246                ret = ssp_send_instruction(data,
 247                                           SSP_MSG2SSP_INST_CHANGE_DELAY, type,
 248                                           (u8 *)&to_send, sizeof(to_send));
 249                if (ret < 0) {
 250                        dev_err(&data->spi->dev,
 251                                "Changing sensor delay failed\n");
 252                        goto derror;
 253                }
 254                break;
 255        default:
 256                data->check_status[type] = SSP_ADD_SENSOR_STATE;
 257                break;
 258        }
 259
 260        data->delay_buf[type] = delay;
 261
 262        if (atomic_inc_return(&data->enable_refcount) == 1)
 263                ssp_enable_wdt_timer(data);
 264
 265        return 0;
 266
 267derror:
 268        return ret;
 269}
 270EXPORT_SYMBOL(ssp_enable_sensor);
 271
 272/**
 273 * ssp_change_delay() - changes data acquisition for sensor
 274 * @data:       sensorhub structure
 275 * @type:       SSP sensor type
 276 * @delay:      delay in ms
 277 *
 278 * Returns 0 or negative value in case of error
 279 */
 280int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
 281                     u32 delay)
 282{
 283        int ret;
 284        struct ssp_instruction to_send;
 285
 286        to_send.a = cpu_to_le32(delay);
 287        to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
 288        to_send.c = data->batch_opt_buf[type];
 289
 290        ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
 291                                   (u8 *)&to_send, sizeof(to_send));
 292        if (ret < 0) {
 293                dev_err(&data->spi->dev, "Changing sensor delay failed\n");
 294                return ret;
 295        }
 296
 297        data->delay_buf[type] = delay;
 298
 299        return 0;
 300}
 301EXPORT_SYMBOL(ssp_change_delay);
 302
 303/**
 304 * ssp_disable_sensor() - disables sensor
 305 *
 306 * @data:       sensorhub structure
 307 * @type:       SSP sensor type
 308 *
 309 * Returns 0 or negative value in case of error
 310 */
 311int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
 312{
 313        int ret;
 314        __le32 command;
 315
 316        if (data->sensor_enable & BIT(type)) {
 317                command = cpu_to_le32(data->delay_buf[type]);
 318
 319                ret = ssp_send_instruction(data,
 320                                           SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
 321                                           type, (u8 *)&command,
 322                                           sizeof(command));
 323                if (ret < 0) {
 324                        dev_err(&data->spi->dev, "Remove sensor fail\n");
 325                        return ret;
 326                }
 327
 328                data->sensor_enable &= ~BIT(type);
 329        }
 330
 331        data->check_status[type] = SSP_ADD_SENSOR_STATE;
 332
 333        if (atomic_dec_and_test(&data->enable_refcount))
 334                ssp_disable_wdt_timer(data);
 335
 336        return 0;
 337}
 338EXPORT_SYMBOL(ssp_disable_sensor);
 339
 340static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
 341{
 342        struct ssp_data *data = dev_id;
 343
 344        /*
 345         * This wrapper is done to preserve error path for ssp_irq_msg, also
 346         * it is defined in different file.
 347         */
 348        ssp_irq_msg(data);
 349
 350        return IRQ_HANDLED;
 351}
 352
 353static int ssp_initialize_mcu(struct ssp_data *data)
 354{
 355        int ret;
 356
 357        ssp_clean_pending_list(data);
 358
 359        ret = ssp_get_chipid(data);
 360        if (ret != SSP_DEVICE_ID) {
 361                dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
 362                        ret < 0 ? "is not working" : "identification failed",
 363                        ret);
 364                return ret < 0 ? ret : -ENODEV;
 365        }
 366
 367        dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
 368
 369        /*
 370         * needs clarification, for now do not want to export all transfer
 371         * methods to sensors' drivers
 372         */
 373        ret = ssp_set_magnetic_matrix(data);
 374        if (ret < 0) {
 375                dev_err(&data->spi->dev,
 376                        "%s - ssp_set_magnetic_matrix failed\n", __func__);
 377                return ret;
 378        }
 379
 380        data->available_sensors = ssp_get_sensor_scanning_info(data);
 381        if (data->available_sensors == 0) {
 382                dev_err(&data->spi->dev,
 383                        "%s - ssp_get_sensor_scanning_info failed\n", __func__);
 384                return -EIO;
 385        }
 386
 387        data->cur_firm_rev = ssp_get_firmware_rev(data);
 388        dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
 389                 data->cur_firm_rev);
 390
 391        return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
 392}
 393
 394/*
 395 * sensorhub can request its reinitialization as some brutal and rare error
 396 * handling. It can be requested from the MCU.
 397 */
 398static void ssp_refresh_task(struct work_struct *work)
 399{
 400        struct ssp_data *data = container_of((struct delayed_work *)work,
 401                                             struct ssp_data, work_refresh);
 402
 403        dev_info(&data->spi->dev, "refreshing\n");
 404
 405        data->reset_cnt++;
 406
 407        if (ssp_initialize_mcu(data) >= 0) {
 408                ssp_sync_available_sensors(data);
 409                if (data->last_ap_state != 0)
 410                        ssp_command(data, data->last_ap_state, 0);
 411
 412                if (data->last_resume_state != 0)
 413                        ssp_command(data, data->last_resume_state, 0);
 414
 415                data->timeout_cnt = 0;
 416                data->com_fail_cnt = 0;
 417        }
 418}
 419
 420int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
 421{
 422        cancel_delayed_work_sync(&data->work_refresh);
 423
 424        return queue_delayed_work(system_power_efficient_wq,
 425                                  &data->work_refresh,
 426                                  msecs_to_jiffies(delay));
 427}
 428
 429#ifdef CONFIG_OF
 430static const struct of_device_id ssp_of_match[] = {
 431        {
 432                .compatible     = "samsung,sensorhub-rinato",
 433                .data           = &ssp_rinato_info,
 434        }, {
 435                .compatible     = "samsung,sensorhub-thermostat",
 436                .data           = &ssp_thermostat_info,
 437        },
 438        {},
 439};
 440MODULE_DEVICE_TABLE(of, ssp_of_match);
 441
 442static struct ssp_data *ssp_parse_dt(struct device *dev)
 443{
 444        int ret;
 445        struct ssp_data *data;
 446        struct device_node *node = dev->of_node;
 447        const struct of_device_id *match;
 448
 449        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 450        if (!data)
 451                return NULL;
 452
 453        data->mcu_ap_gpio = of_get_named_gpio(node, "mcu-ap-gpios", 0);
 454        if (data->mcu_ap_gpio < 0)
 455                return NULL;
 456
 457        data->ap_mcu_gpio = of_get_named_gpio(node, "ap-mcu-gpios", 0);
 458        if (data->ap_mcu_gpio < 0)
 459                return NULL;
 460
 461        data->mcu_reset_gpio = of_get_named_gpio(node, "mcu-reset-gpios", 0);
 462        if (data->mcu_reset_gpio < 0)
 463                return NULL;
 464
 465        ret = devm_gpio_request_one(dev, data->ap_mcu_gpio, GPIOF_OUT_INIT_HIGH,
 466                                    "ap-mcu-gpios");
 467        if (ret)
 468                return NULL;
 469
 470        ret = devm_gpio_request_one(dev, data->mcu_reset_gpio,
 471                                    GPIOF_OUT_INIT_HIGH, "mcu-reset-gpios");
 472        if (ret)
 473                return NULL;
 474
 475        match = of_match_node(ssp_of_match, node);
 476        if (!match)
 477                return NULL;
 478
 479        data->sensorhub_info = match->data;
 480
 481        dev_set_drvdata(dev, data);
 482
 483        return data;
 484}
 485#else
 486static struct ssp_data *ssp_parse_dt(struct device *pdev)
 487{
 488        return NULL;
 489}
 490#endif
 491
 492/**
 493 * ssp_register_consumer() - registers iio consumer in ssp framework
 494 *
 495 * @indio_dev:  consumer iio device
 496 * @type:       ssp sensor type
 497 */
 498void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
 499{
 500        struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
 501
 502        data->sensor_devs[type] = indio_dev;
 503}
 504EXPORT_SYMBOL(ssp_register_consumer);
 505
 506static int ssp_probe(struct spi_device *spi)
 507{
 508        int ret, i;
 509        struct ssp_data *data;
 510
 511        data = ssp_parse_dt(&spi->dev);
 512        if (!data) {
 513                dev_err(&spi->dev, "Failed to find platform data\n");
 514                return -ENODEV;
 515        }
 516
 517        ret = mfd_add_devices(&spi->dev, -1, sensorhub_sensor_devs,
 518                              ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
 519        if (ret < 0) {
 520                dev_err(&spi->dev, "mfd add devices fail\n");
 521                return ret;
 522        }
 523
 524        spi->mode = SPI_MODE_1;
 525        ret = spi_setup(spi);
 526        if (ret < 0) {
 527                dev_err(&spi->dev, "Failed to setup spi\n");
 528                return ret;
 529        }
 530
 531        data->fw_dl_state = SSP_FW_DL_STATE_NONE;
 532        data->spi = spi;
 533        spi_set_drvdata(spi, data);
 534
 535        mutex_init(&data->comm_lock);
 536
 537        for (i = 0; i < SSP_SENSOR_MAX; ++i) {
 538                data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
 539                data->batch_latency_buf[i] = 0;
 540                data->batch_opt_buf[i] = 0;
 541                data->check_status[i] = SSP_INITIALIZATION_STATE;
 542        }
 543
 544        data->delay_buf[SSP_BIO_HRM_LIB] = 100;
 545
 546        data->time_syncing = true;
 547
 548        mutex_init(&data->pending_lock);
 549        INIT_LIST_HEAD(&data->pending_list);
 550
 551        atomic_set(&data->enable_refcount, 0);
 552
 553        INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
 554        INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
 555
 556        timer_setup(&data->wdt_timer, ssp_wdt_timer_func, 0);
 557
 558        ret = request_threaded_irq(data->spi->irq, NULL,
 559                                   ssp_irq_thread_fn,
 560                                   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 561                                   "SSP_Int", data);
 562        if (ret < 0) {
 563                dev_err(&spi->dev, "Irq request fail\n");
 564                goto err_setup_irq;
 565        }
 566
 567        /* Let's start with enabled one so irq balance could be ok */
 568        data->shut_down = false;
 569
 570        /* just to avoid unbalanced irq set wake up */
 571        enable_irq_wake(data->spi->irq);
 572
 573        data->fw_dl_state = ssp_check_fwbl(data);
 574        if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
 575                ret = ssp_initialize_mcu(data);
 576                if (ret < 0) {
 577                        dev_err(&spi->dev, "Initialize_mcu failed\n");
 578                        goto err_read_reg;
 579                }
 580        } else {
 581                dev_err(&spi->dev, "Firmware version not supported\n");
 582                ret = -EPERM;
 583                goto err_read_reg;
 584        }
 585
 586        return 0;
 587
 588err_read_reg:
 589        free_irq(data->spi->irq, data);
 590err_setup_irq:
 591        mutex_destroy(&data->pending_lock);
 592        mutex_destroy(&data->comm_lock);
 593
 594        dev_err(&spi->dev, "Probe failed!\n");
 595
 596        return ret;
 597}
 598
 599static int ssp_remove(struct spi_device *spi)
 600{
 601        struct ssp_data *data = spi_get_drvdata(spi);
 602
 603        if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
 604                dev_err(&data->spi->dev,
 605                        "SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
 606
 607        ssp_enable_mcu(data, false);
 608        ssp_disable_wdt_timer(data);
 609
 610        ssp_clean_pending_list(data);
 611
 612        free_irq(data->spi->irq, data);
 613
 614        del_timer_sync(&data->wdt_timer);
 615        cancel_work_sync(&data->work_wdt);
 616
 617        mutex_destroy(&data->comm_lock);
 618        mutex_destroy(&data->pending_lock);
 619
 620        mfd_remove_devices(&spi->dev);
 621
 622        return 0;
 623}
 624
 625#ifdef CONFIG_PM_SLEEP
 626static int ssp_suspend(struct device *dev)
 627{
 628        int ret;
 629        struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
 630
 631        data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
 632
 633        if (atomic_read(&data->enable_refcount) > 0)
 634                ssp_disable_wdt_timer(data);
 635
 636        ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
 637        if (ret < 0) {
 638                dev_err(&data->spi->dev,
 639                        "%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
 640
 641                ssp_enable_wdt_timer(data);
 642                return ret;
 643        }
 644
 645        data->time_syncing = false;
 646        disable_irq(data->spi->irq);
 647
 648        return 0;
 649}
 650
 651static int ssp_resume(struct device *dev)
 652{
 653        int ret;
 654        struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
 655
 656        enable_irq(data->spi->irq);
 657
 658        if (atomic_read(&data->enable_refcount) > 0)
 659                ssp_enable_wdt_timer(data);
 660
 661        ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
 662        if (ret < 0) {
 663                dev_err(&data->spi->dev,
 664                        "%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
 665                ssp_disable_wdt_timer(data);
 666                return ret;
 667        }
 668
 669        /* timesyncing is set by MCU */
 670        data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
 671
 672        return 0;
 673}
 674#endif /* CONFIG_PM_SLEEP */
 675
 676static const struct dev_pm_ops ssp_pm_ops = {
 677        SET_SYSTEM_SLEEP_PM_OPS(ssp_suspend, ssp_resume)
 678};
 679
 680static struct spi_driver ssp_driver = {
 681        .probe = ssp_probe,
 682        .remove = ssp_remove,
 683        .driver = {
 684                .pm = &ssp_pm_ops,
 685                .of_match_table = of_match_ptr(ssp_of_match),
 686                .name = "sensorhub"
 687        },
 688};
 689
 690module_spi_driver(ssp_driver);
 691
 692MODULE_DESCRIPTION("ssp sensorhub driver");
 693MODULE_AUTHOR("Samsung Electronics");
 694MODULE_LICENSE("GPL");
 695