Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
0004  */
0005 
0006 #include <linux/iio/iio.h>
0007 #include <linux/interrupt.h>
0008 #include <linux/io.h>
0009 #include <linux/mfd/core.h>
0010 #include <linux/mod_devicetable.h>
0011 #include <linux/module.h>
0012 #include <linux/property.h>
0013 
0014 #include "ssp.h"
0015 
0016 #define SSP_WDT_TIME            10000
0017 #define SSP_LIMIT_RESET_CNT     20
0018 #define SSP_LIMIT_TIMEOUT_CNT       3
0019 
0020 /* It is possible that it is max clk rate for version 1.0 of bootcode */
0021 #define SSP_BOOT_SPI_HZ 400000
0022 
0023 /*
0024  * These fields can look enigmatic but this structure is used mainly to flat
0025  * some values and depends on command type.
0026  */
0027 struct ssp_instruction {
0028     __le32 a;
0029     __le32 b;
0030     u8 c;
0031 } __attribute__((__packed__));
0032 
0033 static const u8 ssp_magnitude_table[] = {110, 85, 171, 71, 203, 195, 0, 67,
0034     208, 56, 175, 244, 206, 213, 0, 92, 250, 0, 55, 48, 189, 252, 171,
0035     243, 13, 45, 250};
0036 
0037 static const struct ssp_sensorhub_info ssp_rinato_info = {
0038     .fw_name = "ssp_B2.fw",
0039     .fw_crashed_name = "ssp_crashed.fw",
0040     .fw_rev = 14052300,
0041     .mag_table = ssp_magnitude_table,
0042     .mag_length = ARRAY_SIZE(ssp_magnitude_table),
0043 };
0044 
0045 static const struct ssp_sensorhub_info ssp_thermostat_info = {
0046     .fw_name = "thermostat_B2.fw",
0047     .fw_crashed_name = "ssp_crashed.fw",
0048     .fw_rev = 14080600,
0049     .mag_table = ssp_magnitude_table,
0050     .mag_length = ARRAY_SIZE(ssp_magnitude_table),
0051 };
0052 
0053 static const struct mfd_cell sensorhub_sensor_devs[] = {
0054     {
0055         .name = "ssp-accelerometer",
0056     },
0057     {
0058         .name = "ssp-gyroscope",
0059     },
0060 };
0061 
0062 static void ssp_toggle_mcu_reset_gpio(struct ssp_data *data)
0063 {
0064     gpiod_set_value(data->mcu_reset_gpiod, 0);
0065     usleep_range(1000, 1200);
0066     gpiod_set_value(data->mcu_reset_gpiod, 1);
0067     msleep(50);
0068 }
0069 
0070 static void ssp_sync_available_sensors(struct ssp_data *data)
0071 {
0072     int i, ret;
0073 
0074     for (i = 0; i < SSP_SENSOR_MAX; ++i) {
0075         if (data->available_sensors & BIT(i)) {
0076             ret = ssp_enable_sensor(data, i, data->delay_buf[i]);
0077             if (ret < 0) {
0078                 dev_err(&data->spi->dev,
0079                     "Sync sensor nr: %d fail\n", i);
0080                 continue;
0081             }
0082         }
0083     }
0084 
0085     ret = ssp_command(data, SSP_MSG2SSP_AP_MCU_SET_DUMPMODE,
0086               data->mcu_dump_mode);
0087     if (ret < 0)
0088         dev_err(&data->spi->dev,
0089             "SSP_MSG2SSP_AP_MCU_SET_DUMPMODE failed\n");
0090 }
0091 
0092 static void ssp_enable_mcu(struct ssp_data *data, bool enable)
0093 {
0094     dev_info(&data->spi->dev, "current shutdown = %d, old = %d\n", enable,
0095          data->shut_down);
0096 
0097     if (enable && data->shut_down) {
0098         data->shut_down = false;
0099         enable_irq(data->spi->irq);
0100         enable_irq_wake(data->spi->irq);
0101     } else if (!enable && !data->shut_down) {
0102         data->shut_down = true;
0103         disable_irq(data->spi->irq);
0104         disable_irq_wake(data->spi->irq);
0105     } else {
0106         dev_warn(&data->spi->dev, "current shutdown = %d, old = %d\n",
0107              enable, data->shut_down);
0108     }
0109 }
0110 
0111 /*
0112  * This function is the first one which communicates with the mcu so it is
0113  * possible that the first attempt will fail
0114  */
0115 static int ssp_check_fwbl(struct ssp_data *data)
0116 {
0117     int retries = 0;
0118 
0119     while (retries++ < 5) {
0120         data->cur_firm_rev = ssp_get_firmware_rev(data);
0121         if (data->cur_firm_rev == SSP_INVALID_REVISION ||
0122             data->cur_firm_rev == SSP_INVALID_REVISION2) {
0123             dev_warn(&data->spi->dev,
0124                  "Invalid revision, trying %d time\n", retries);
0125         } else {
0126             break;
0127         }
0128     }
0129 
0130     if (data->cur_firm_rev == SSP_INVALID_REVISION ||
0131         data->cur_firm_rev == SSP_INVALID_REVISION2) {
0132         dev_err(&data->spi->dev, "SSP_INVALID_REVISION\n");
0133         return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
0134     }
0135 
0136     dev_info(&data->spi->dev,
0137          "MCU Firm Rev : Old = %8u, New = %8u\n",
0138          data->cur_firm_rev,
0139          data->sensorhub_info->fw_rev);
0140 
0141     if (data->cur_firm_rev != data->sensorhub_info->fw_rev)
0142         return SSP_FW_DL_STATE_NEED_TO_SCHEDULE;
0143 
0144     return SSP_FW_DL_STATE_NONE;
0145 }
0146 
0147 static void ssp_reset_mcu(struct ssp_data *data)
0148 {
0149     ssp_enable_mcu(data, false);
0150     ssp_clean_pending_list(data);
0151     ssp_toggle_mcu_reset_gpio(data);
0152     ssp_enable_mcu(data, true);
0153 }
0154 
0155 static void ssp_wdt_work_func(struct work_struct *work)
0156 {
0157     struct ssp_data *data = container_of(work, struct ssp_data, work_wdt);
0158 
0159     dev_err(&data->spi->dev, "%s - Sensor state: 0x%x, RC: %u, CC: %u\n",
0160         __func__, data->available_sensors, data->reset_cnt,
0161         data->com_fail_cnt);
0162 
0163     ssp_reset_mcu(data);
0164     data->com_fail_cnt = 0;
0165     data->timeout_cnt = 0;
0166 }
0167 
0168 static void ssp_wdt_timer_func(struct timer_list *t)
0169 {
0170     struct ssp_data *data = from_timer(data, t, wdt_timer);
0171 
0172     switch (data->fw_dl_state) {
0173     case SSP_FW_DL_STATE_FAIL:
0174     case SSP_FW_DL_STATE_DOWNLOADING:
0175     case SSP_FW_DL_STATE_SYNC:
0176         goto _mod;
0177     }
0178 
0179     if (data->timeout_cnt > SSP_LIMIT_TIMEOUT_CNT ||
0180         data->com_fail_cnt > SSP_LIMIT_RESET_CNT)
0181         queue_work(system_power_efficient_wq, &data->work_wdt);
0182 _mod:
0183     mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
0184 }
0185 
0186 static void ssp_enable_wdt_timer(struct ssp_data *data)
0187 {
0188     mod_timer(&data->wdt_timer, jiffies + msecs_to_jiffies(SSP_WDT_TIME));
0189 }
0190 
0191 static void ssp_disable_wdt_timer(struct ssp_data *data)
0192 {
0193     del_timer_sync(&data->wdt_timer);
0194     cancel_work_sync(&data->work_wdt);
0195 }
0196 
0197 /**
0198  * ssp_get_sensor_delay() - gets sensor data acquisition period
0199  * @data:   sensorhub structure
0200  * @type:   SSP sensor type
0201  *
0202  * Returns acquisition period in ms
0203  */
0204 u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type type)
0205 {
0206     return data->delay_buf[type];
0207 }
0208 EXPORT_SYMBOL_NS(ssp_get_sensor_delay, IIO_SSP_SENSORS);
0209 
0210 /**
0211  * ssp_enable_sensor() - enables data acquisition for sensor
0212  * @data:   sensorhub structure
0213  * @type:   SSP sensor type
0214  * @delay:  delay in ms
0215  *
0216  * Returns 0 or negative value in case of error
0217  */
0218 int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
0219               u32 delay)
0220 {
0221     int ret;
0222     struct ssp_instruction to_send;
0223 
0224     to_send.a = cpu_to_le32(delay);
0225     to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
0226     to_send.c = data->batch_opt_buf[type];
0227 
0228     switch (data->check_status[type]) {
0229     case SSP_INITIALIZATION_STATE:
0230         /* do calibration step, now just enable */
0231     case SSP_ADD_SENSOR_STATE:
0232         ret = ssp_send_instruction(data,
0233                        SSP_MSG2SSP_INST_BYPASS_SENSOR_ADD,
0234                        type,
0235                        (u8 *)&to_send, sizeof(to_send));
0236         if (ret < 0) {
0237             dev_err(&data->spi->dev, "Enabling sensor failed\n");
0238             data->check_status[type] = SSP_NO_SENSOR_STATE;
0239             goto derror;
0240         }
0241 
0242         data->sensor_enable |= BIT(type);
0243         data->check_status[type] = SSP_RUNNING_SENSOR_STATE;
0244         break;
0245     case SSP_RUNNING_SENSOR_STATE:
0246         ret = ssp_send_instruction(data,
0247                        SSP_MSG2SSP_INST_CHANGE_DELAY, type,
0248                        (u8 *)&to_send, sizeof(to_send));
0249         if (ret < 0) {
0250             dev_err(&data->spi->dev,
0251                 "Changing sensor delay failed\n");
0252             goto derror;
0253         }
0254         break;
0255     default:
0256         data->check_status[type] = SSP_ADD_SENSOR_STATE;
0257         break;
0258     }
0259 
0260     data->delay_buf[type] = delay;
0261 
0262     if (atomic_inc_return(&data->enable_refcount) == 1)
0263         ssp_enable_wdt_timer(data);
0264 
0265     return 0;
0266 
0267 derror:
0268     return ret;
0269 }
0270 EXPORT_SYMBOL_NS(ssp_enable_sensor, IIO_SSP_SENSORS);
0271 
0272 /**
0273  * ssp_change_delay() - changes data acquisition for sensor
0274  * @data:   sensorhub structure
0275  * @type:   SSP sensor type
0276  * @delay:  delay in ms
0277  *
0278  * Returns 0 or negative value in case of error
0279  */
0280 int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
0281              u32 delay)
0282 {
0283     int ret;
0284     struct ssp_instruction to_send;
0285 
0286     to_send.a = cpu_to_le32(delay);
0287     to_send.b = cpu_to_le32(data->batch_latency_buf[type]);
0288     to_send.c = data->batch_opt_buf[type];
0289 
0290     ret = ssp_send_instruction(data, SSP_MSG2SSP_INST_CHANGE_DELAY, type,
0291                    (u8 *)&to_send, sizeof(to_send));
0292     if (ret < 0) {
0293         dev_err(&data->spi->dev, "Changing sensor delay failed\n");
0294         return ret;
0295     }
0296 
0297     data->delay_buf[type] = delay;
0298 
0299     return 0;
0300 }
0301 EXPORT_SYMBOL_NS(ssp_change_delay, IIO_SSP_SENSORS);
0302 
0303 /**
0304  * ssp_disable_sensor() - disables sensor
0305  *
0306  * @data:   sensorhub structure
0307  * @type:   SSP sensor type
0308  *
0309  * Returns 0 or negative value in case of error
0310  */
0311 int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type)
0312 {
0313     int ret;
0314     __le32 command;
0315 
0316     if (data->sensor_enable & BIT(type)) {
0317         command = cpu_to_le32(data->delay_buf[type]);
0318 
0319         ret = ssp_send_instruction(data,
0320                        SSP_MSG2SSP_INST_BYPASS_SENSOR_RM,
0321                        type, (u8 *)&command,
0322                        sizeof(command));
0323         if (ret < 0) {
0324             dev_err(&data->spi->dev, "Remove sensor fail\n");
0325             return ret;
0326         }
0327 
0328         data->sensor_enable &= ~BIT(type);
0329     }
0330 
0331     data->check_status[type] = SSP_ADD_SENSOR_STATE;
0332 
0333     if (atomic_dec_and_test(&data->enable_refcount))
0334         ssp_disable_wdt_timer(data);
0335 
0336     return 0;
0337 }
0338 EXPORT_SYMBOL_NS(ssp_disable_sensor, IIO_SSP_SENSORS);
0339 
0340 static irqreturn_t ssp_irq_thread_fn(int irq, void *dev_id)
0341 {
0342     struct ssp_data *data = dev_id;
0343 
0344     /*
0345      * This wrapper is done to preserve error path for ssp_irq_msg, also
0346      * it is defined in different file.
0347      */
0348     ssp_irq_msg(data);
0349 
0350     return IRQ_HANDLED;
0351 }
0352 
0353 static int ssp_initialize_mcu(struct ssp_data *data)
0354 {
0355     int ret;
0356 
0357     ssp_clean_pending_list(data);
0358 
0359     ret = ssp_get_chipid(data);
0360     if (ret != SSP_DEVICE_ID) {
0361         dev_err(&data->spi->dev, "%s - MCU %s ret = %d\n", __func__,
0362             ret < 0 ? "is not working" : "identification failed",
0363             ret);
0364         return ret < 0 ? ret : -ENODEV;
0365     }
0366 
0367     dev_info(&data->spi->dev, "MCU device ID = %d\n", ret);
0368 
0369     /*
0370      * needs clarification, for now do not want to export all transfer
0371      * methods to sensors' drivers
0372      */
0373     ret = ssp_set_magnetic_matrix(data);
0374     if (ret < 0) {
0375         dev_err(&data->spi->dev,
0376             "%s - ssp_set_magnetic_matrix failed\n", __func__);
0377         return ret;
0378     }
0379 
0380     data->available_sensors = ssp_get_sensor_scanning_info(data);
0381     if (data->available_sensors == 0) {
0382         dev_err(&data->spi->dev,
0383             "%s - ssp_get_sensor_scanning_info failed\n", __func__);
0384         return -EIO;
0385     }
0386 
0387     data->cur_firm_rev = ssp_get_firmware_rev(data);
0388     dev_info(&data->spi->dev, "MCU Firm Rev : New = %8u\n",
0389          data->cur_firm_rev);
0390 
0391     return ssp_command(data, SSP_MSG2SSP_AP_MCU_DUMP_CHECK, 0);
0392 }
0393 
0394 /*
0395  * sensorhub can request its reinitialization as some brutal and rare error
0396  * handling. It can be requested from the MCU.
0397  */
0398 static void ssp_refresh_task(struct work_struct *work)
0399 {
0400     struct ssp_data *data = container_of((struct delayed_work *)work,
0401                          struct ssp_data, work_refresh);
0402 
0403     dev_info(&data->spi->dev, "refreshing\n");
0404 
0405     data->reset_cnt++;
0406 
0407     if (ssp_initialize_mcu(data) >= 0) {
0408         ssp_sync_available_sensors(data);
0409         if (data->last_ap_state != 0)
0410             ssp_command(data, data->last_ap_state, 0);
0411 
0412         if (data->last_resume_state != 0)
0413             ssp_command(data, data->last_resume_state, 0);
0414 
0415         data->timeout_cnt = 0;
0416         data->com_fail_cnt = 0;
0417     }
0418 }
0419 
0420 int ssp_queue_ssp_refresh_task(struct ssp_data *data, unsigned int delay)
0421 {
0422     cancel_delayed_work_sync(&data->work_refresh);
0423 
0424     return queue_delayed_work(system_power_efficient_wq,
0425                   &data->work_refresh,
0426                   msecs_to_jiffies(delay));
0427 }
0428 
0429 static const struct of_device_id ssp_of_match[] = {
0430     {
0431         .compatible = "samsung,sensorhub-rinato",
0432         .data       = &ssp_rinato_info,
0433     }, {
0434         .compatible = "samsung,sensorhub-thermostat",
0435         .data       = &ssp_thermostat_info,
0436     },
0437     {},
0438 };
0439 MODULE_DEVICE_TABLE(of, ssp_of_match);
0440 
0441 static struct ssp_data *ssp_parse_dt(struct device *dev)
0442 {
0443     struct ssp_data *data;
0444 
0445     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0446     if (!data)
0447         return NULL;
0448 
0449     data->mcu_ap_gpiod = devm_gpiod_get(dev, "mcu-ap", GPIOD_IN);
0450     if (IS_ERR(data->mcu_ap_gpiod))
0451         return NULL;
0452 
0453     data->ap_mcu_gpiod = devm_gpiod_get(dev, "ap-mcu", GPIOD_OUT_HIGH);
0454     if (IS_ERR(data->ap_mcu_gpiod))
0455         return NULL;
0456 
0457     data->mcu_reset_gpiod = devm_gpiod_get(dev, "mcu-reset",
0458                            GPIOD_OUT_HIGH);
0459     if (IS_ERR(data->mcu_reset_gpiod))
0460         return NULL;
0461 
0462     data->sensorhub_info = device_get_match_data(dev);
0463 
0464     dev_set_drvdata(dev, data);
0465 
0466     return data;
0467 }
0468 
0469 /**
0470  * ssp_register_consumer() - registers iio consumer in ssp framework
0471  *
0472  * @indio_dev:  consumer iio device
0473  * @type:   ssp sensor type
0474  */
0475 void ssp_register_consumer(struct iio_dev *indio_dev, enum ssp_sensor_type type)
0476 {
0477     struct ssp_data *data = dev_get_drvdata(indio_dev->dev.parent->parent);
0478 
0479     data->sensor_devs[type] = indio_dev;
0480 }
0481 EXPORT_SYMBOL_NS(ssp_register_consumer, IIO_SSP_SENSORS);
0482 
0483 static int ssp_probe(struct spi_device *spi)
0484 {
0485     int ret, i;
0486     struct ssp_data *data;
0487 
0488     data = ssp_parse_dt(&spi->dev);
0489     if (!data) {
0490         dev_err(&spi->dev, "Failed to find platform data\n");
0491         return -ENODEV;
0492     }
0493 
0494     ret = mfd_add_devices(&spi->dev, PLATFORM_DEVID_NONE,
0495                   sensorhub_sensor_devs,
0496                   ARRAY_SIZE(sensorhub_sensor_devs), NULL, 0, NULL);
0497     if (ret < 0) {
0498         dev_err(&spi->dev, "mfd add devices fail\n");
0499         return ret;
0500     }
0501 
0502     spi->mode = SPI_MODE_1;
0503     ret = spi_setup(spi);
0504     if (ret < 0) {
0505         dev_err(&spi->dev, "Failed to setup spi\n");
0506         return ret;
0507     }
0508 
0509     data->fw_dl_state = SSP_FW_DL_STATE_NONE;
0510     data->spi = spi;
0511     spi_set_drvdata(spi, data);
0512 
0513     mutex_init(&data->comm_lock);
0514 
0515     for (i = 0; i < SSP_SENSOR_MAX; ++i) {
0516         data->delay_buf[i] = SSP_DEFAULT_POLLING_DELAY;
0517         data->batch_latency_buf[i] = 0;
0518         data->batch_opt_buf[i] = 0;
0519         data->check_status[i] = SSP_INITIALIZATION_STATE;
0520     }
0521 
0522     data->delay_buf[SSP_BIO_HRM_LIB] = 100;
0523 
0524     data->time_syncing = true;
0525 
0526     mutex_init(&data->pending_lock);
0527     INIT_LIST_HEAD(&data->pending_list);
0528 
0529     atomic_set(&data->enable_refcount, 0);
0530 
0531     INIT_WORK(&data->work_wdt, ssp_wdt_work_func);
0532     INIT_DELAYED_WORK(&data->work_refresh, ssp_refresh_task);
0533 
0534     timer_setup(&data->wdt_timer, ssp_wdt_timer_func, 0);
0535 
0536     ret = request_threaded_irq(data->spi->irq, NULL,
0537                    ssp_irq_thread_fn,
0538                    IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
0539                    "SSP_Int", data);
0540     if (ret < 0) {
0541         dev_err(&spi->dev, "Irq request fail\n");
0542         goto err_setup_irq;
0543     }
0544 
0545     /* Let's start with enabled one so irq balance could be ok */
0546     data->shut_down = false;
0547 
0548     /* just to avoid unbalanced irq set wake up */
0549     enable_irq_wake(data->spi->irq);
0550 
0551     data->fw_dl_state = ssp_check_fwbl(data);
0552     if (data->fw_dl_state == SSP_FW_DL_STATE_NONE) {
0553         ret = ssp_initialize_mcu(data);
0554         if (ret < 0) {
0555             dev_err(&spi->dev, "Initialize_mcu failed\n");
0556             goto err_read_reg;
0557         }
0558     } else {
0559         dev_err(&spi->dev, "Firmware version not supported\n");
0560         ret = -EPERM;
0561         goto err_read_reg;
0562     }
0563 
0564     return 0;
0565 
0566 err_read_reg:
0567     free_irq(data->spi->irq, data);
0568 err_setup_irq:
0569     mutex_destroy(&data->pending_lock);
0570     mutex_destroy(&data->comm_lock);
0571 
0572     dev_err(&spi->dev, "Probe failed!\n");
0573 
0574     return ret;
0575 }
0576 
0577 static void ssp_remove(struct spi_device *spi)
0578 {
0579     struct ssp_data *data = spi_get_drvdata(spi);
0580 
0581     if (ssp_command(data, SSP_MSG2SSP_AP_STATUS_SHUTDOWN, 0) < 0)
0582         dev_err(&data->spi->dev,
0583             "SSP_MSG2SSP_AP_STATUS_SHUTDOWN failed\n");
0584 
0585     ssp_enable_mcu(data, false);
0586     ssp_disable_wdt_timer(data);
0587 
0588     ssp_clean_pending_list(data);
0589 
0590     free_irq(data->spi->irq, data);
0591 
0592     del_timer_sync(&data->wdt_timer);
0593     cancel_work_sync(&data->work_wdt);
0594 
0595     mutex_destroy(&data->comm_lock);
0596     mutex_destroy(&data->pending_lock);
0597 
0598     mfd_remove_devices(&spi->dev);
0599 }
0600 
0601 static int ssp_suspend(struct device *dev)
0602 {
0603     int ret;
0604     struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
0605 
0606     data->last_resume_state = SSP_MSG2SSP_AP_STATUS_SUSPEND;
0607 
0608     if (atomic_read(&data->enable_refcount) > 0)
0609         ssp_disable_wdt_timer(data);
0610 
0611     ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_SUSPEND, 0);
0612     if (ret < 0) {
0613         dev_err(&data->spi->dev,
0614             "%s SSP_MSG2SSP_AP_STATUS_SUSPEND failed\n", __func__);
0615 
0616         ssp_enable_wdt_timer(data);
0617         return ret;
0618     }
0619 
0620     data->time_syncing = false;
0621     disable_irq(data->spi->irq);
0622 
0623     return 0;
0624 }
0625 
0626 static int ssp_resume(struct device *dev)
0627 {
0628     int ret;
0629     struct ssp_data *data = spi_get_drvdata(to_spi_device(dev));
0630 
0631     enable_irq(data->spi->irq);
0632 
0633     if (atomic_read(&data->enable_refcount) > 0)
0634         ssp_enable_wdt_timer(data);
0635 
0636     ret = ssp_command(data, SSP_MSG2SSP_AP_STATUS_RESUME, 0);
0637     if (ret < 0) {
0638         dev_err(&data->spi->dev,
0639             "%s SSP_MSG2SSP_AP_STATUS_RESUME failed\n", __func__);
0640         ssp_disable_wdt_timer(data);
0641         return ret;
0642     }
0643 
0644     /* timesyncing is set by MCU */
0645     data->last_resume_state = SSP_MSG2SSP_AP_STATUS_RESUME;
0646 
0647     return 0;
0648 }
0649 
0650 static DEFINE_SIMPLE_DEV_PM_OPS(ssp_pm_ops, ssp_suspend, ssp_resume);
0651 
0652 static struct spi_driver ssp_driver = {
0653     .probe = ssp_probe,
0654     .remove = ssp_remove,
0655     .driver = {
0656         .pm = pm_sleep_ptr(&ssp_pm_ops),
0657         .of_match_table = ssp_of_match,
0658         .name = "sensorhub"
0659     },
0660 };
0661 
0662 module_spi_driver(ssp_driver);
0663 
0664 MODULE_DESCRIPTION("ssp sensorhub driver");
0665 MODULE_AUTHOR("Samsung Electronics");
0666 MODULE_LICENSE("GPL");