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