void stml0xx_irq_wake_work_func(struct work_struct *work) { int err; unsigned short irq_status; u32 irq2_status; struct stml0xx_work_struct *stm_ws = (struct stml0xx_work_struct *)work; struct stml0xx_data *ps_stml0xx = stml0xx_misc_data; unsigned char buf[SPI_MSG_SIZE]; dev_dbg(&stml0xx_misc_data->spi->dev, "stml0xx_irq_wake_work_func"); mutex_lock(&ps_stml0xx->lock); if (ps_stml0xx->mode == BOOTMODE) goto EXIT_NO_WAKE; if (ps_stml0xx->is_suspended) { dev_dbg(&stml0xx_misc_data->spi->dev, "setting pending_wake_work [true]"); ps_stml0xx->pending_wake_work = true; goto EXIT_NO_WAKE; } stml0xx_wake(ps_stml0xx); err = stml0xx_spi_read_msg_data(SPI_MSG_TYPE_READ_WAKE_IRQ_DATA, buf, sizeof(buf), RESET_ALLOWED); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading from stml0xx failed"); goto EXIT; } /* read interrupt mask register */ irq_status = (buf[WAKE_IRQ_IDX_STATUS_MED] << 8) | buf[WAKE_IRQ_IDX_STATUS_LO]; /* read algorithm interrupt status register */ irq2_status = (buf[WAKE_IRQ_IDX_ALGO_STATUS_HI] << 16) | (buf[WAKE_IRQ_IDX_ALGO_STATUS_MED] << 8) | buf[WAKE_IRQ_IDX_ALGO_STATUS_LO]; /* Check all other status bits */ if (irq_status & M_PROXIMITY) { stml0xx_as_data_buffer_write( ps_stml0xx, DT_PROX, &buf[WAKE_IRQ_IDX_PROX], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Proximity distance %d", buf[WAKE_IRQ_IDX_PROX]); } if (irq_status & M_COVER) { int state = 0; if (buf[WAKE_IRQ_IDX_COVER] == STML0XX_HALL_NORTH) state = 1; else state = 0; input_report_switch(ps_stml0xx->input_dev, SW_LID, state); input_sync(ps_stml0xx->input_dev); dev_err(&stml0xx_misc_data->spi->dev, "Cover status: %d", state); } if (irq_status & M_HEADSET) { uint8_t new_state; new_state = buf[WAKE_IRQ_IDX_HEADSET]; switch (Headset_State) { case SH_HEADSET_BUTTON_1: if (!(new_state & SH_HEADSET_BUTTON_1_DOWN)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 1 released"); Headset_State = SH_HEADSET_INSERTED; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_1_keycode, 0); input_sync(ps_stml0xx->input_dev); } break; case SH_HEADSET_BUTTON_2: if (!(new_state & SH_HEADSET_BUTTON_2_DOWN)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 2 released"); Headset_State = SH_HEADSET_INSERTED; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_2_keycode, 0); input_sync(ps_stml0xx->input_dev); } break; case SH_HEADSET_BUTTON_3: if (!(new_state & SH_HEADSET_BUTTON_3_DOWN)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 3 released"); Headset_State = SH_HEADSET_INSERTED; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_3_keycode, 0); input_sync(ps_stml0xx->input_dev); } break; case SH_HEADSET_BUTTON_4: if (!(new_state & SH_HEADSET_BUTTON_4_DOWN)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 4 released"); Headset_State = SH_HEADSET_INSERTED; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_4_keycode, 0); input_sync(ps_stml0xx->input_dev); } break; default: break; } if (Headset_State == SH_HEADPHONE_INSERTED) { if (!(new_state & SH_HEADPHONE_DETECTED)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headphone removed"); Headset_State = SH_HEADSET_REMOVED; input_report_switch(ps_stml0xx->input_dev, SW_HEADPHONE_INSERT, 0); input_sync(ps_stml0xx->input_dev); } } else if (Headset_State == SH_HEADSET_INSERTED) { if (!(new_state & SH_HEADSET_DETECTED)) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset removed"); Headset_State = SH_HEADSET_REMOVED; input_report_switch(ps_stml0xx->input_dev, SW_HEADPHONE_INSERT, 0); input_report_switch(ps_stml0xx->input_dev, SW_MICROPHONE_INSERT, 0); input_sync(ps_stml0xx->input_dev); } } if (Headset_State == SH_HEADSET_REMOVED) { if (new_state & SH_HEADPHONE_DETECTED) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headphone inserted"); Headset_State = SH_HEADPHONE_INSERTED; input_report_switch(ps_stml0xx->input_dev, SW_HEADPHONE_INSERT, 1); input_sync(ps_stml0xx->input_dev); } else if (new_state & SH_HEADSET_DETECTED) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset inserted"); Headset_State = SH_HEADSET_INSERTED; input_report_switch(ps_stml0xx->input_dev, SW_HEADPHONE_INSERT, 1); input_report_switch(ps_stml0xx->input_dev, SW_MICROPHONE_INSERT, 1); input_sync(ps_stml0xx->input_dev); } } if (Headset_State == SH_HEADSET_INSERTED) { if (new_state & SH_HEADSET_BUTTON_1_DOWN) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 1 pressed"); Headset_State = SH_HEADSET_BUTTON_1; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_1_keycode, 1); input_sync(ps_stml0xx->input_dev); } else if (new_state & SH_HEADSET_BUTTON_2_DOWN) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 2 pressed"); Headset_State = SH_HEADSET_BUTTON_2; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_2_keycode, 1); input_sync(ps_stml0xx->input_dev); } else if (new_state & SH_HEADSET_BUTTON_3_DOWN) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 3 pressed"); Headset_State = SH_HEADSET_BUTTON_3; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_3_keycode, 1); input_sync(ps_stml0xx->input_dev); } else if (new_state & SH_HEADSET_BUTTON_4_DOWN) { dev_dbg(&stml0xx_misc_data->spi->dev, "Headset button 4 pressed"); Headset_State = SH_HEADSET_BUTTON_4; input_report_key(ps_stml0xx->input_dev, stml0xx_misc_data->pdata->headset_button_4_keycode, 1); input_sync(ps_stml0xx->input_dev); } } } if (irq_status & M_FLATUP) { stml0xx_as_data_buffer_write( ps_stml0xx, DT_FLAT_UP, &buf[WAKE_IRQ_IDX_FLAT], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Flat up %d", buf[WAKE_IRQ_IDX_FLAT]); } if (irq_status & M_FLATDOWN) { stml0xx_as_data_buffer_write(ps_stml0xx, DT_FLAT_DOWN, &buf[WAKE_IRQ_IDX_FLAT], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Flat down %d", buf[WAKE_IRQ_IDX_FLAT]); } if (irq_status & M_STOWED) { stml0xx_as_data_buffer_write( ps_stml0xx, DT_STOWED, &buf[WAKE_IRQ_IDX_STOWED], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Stowed status %d", buf[WAKE_IRQ_IDX_STOWED]); } if (irq_status & M_CAMERA_ACT) { stml0xx_as_data_buffer_write(ps_stml0xx, DT_CAMERA_ACT, &buf[WAKE_IRQ_IDX_CAMERA], 2, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Camera: %d", STM16_TO_HOST(CAMERA_VALUE, &buf[WAKE_IRQ_IDX_CAMERA])); input_report_key(ps_stml0xx->input_dev, KEY_CAMERA, 1); input_report_key(ps_stml0xx->input_dev, KEY_CAMERA, 0); input_sync(ps_stml0xx->input_dev); dev_dbg(&stml0xx_misc_data->spi->dev, "Report camkey toggle"); } if (irq_status & M_SIM) { stml0xx_as_data_buffer_write( ps_stml0xx, DT_SIM, &buf[WAKE_IRQ_IDX_SIM], 2, 0, stm_ws->ts_ns); /* This is one shot sensor */ stml0xx_g_wake_sensor_state &= (~M_SIM); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending SIM Value=%d", STM16_TO_HOST(SIM_DATA, &buf[WAKE_IRQ_IDX_SIM])); } if (irq2_status & M_MMOVEME) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STML0XX_CLIENT_MASK) | M_MMOVEME; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_MMMOVE, &status, 1); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending meaningful movement event"); } if (irq2_status & M_NOMMOVE) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STML0XX_CLIENT_MASK) | M_NOMMOVE; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_NOMOVE, &status, 1); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending no meaningful movement event"); } if (irq2_status & M_ALGO_MODALITY) { buf[WAKE_IRQ_IDX_MODALITY + ALGO_TYPE] = STML0XX_IDX_MODALITY; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_ALGO_EVT, &buf[WAKE_IRQ_IDX_MODALITY], 8); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending modality event"); } if (irq2_status & M_ALGO_ORIENTATION) { buf[WAKE_IRQ_IDX_MODALITY_ORIENT + ALGO_TYPE] = STML0XX_IDX_ORIENTATION; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_ALGO_EVT, &buf[WAKE_IRQ_IDX_MODALITY_ORIENT], 8); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending orientation event"); } if (irq2_status & M_ALGO_STOWED) { buf[WAKE_IRQ_IDX_MODALITY_STOWED + ALGO_TYPE] = STML0XX_IDX_STOWED; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_ALGO_EVT, &buf[WAKE_IRQ_IDX_MODALITY_STOWED], 8); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending stowed event"); } if (irq2_status & M_ALGO_ACCUM_MODALITY) { buf[WAKE_IRQ_IDX_MODALITY_ACCUM + ALGO_TYPE] = STML0XX_IDX_ACCUM_MODALITY; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_ALGO_EVT, &buf[WAKE_IRQ_IDX_MODALITY_ACCUM], 8); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending accum modality event"); } if (irq2_status & M_ALGO_ACCUM_MVMT) { buf[WAKE_IRQ_IDX_MODALITY_ACCUM_MVMT + ALGO_TYPE] = STML0XX_IDX_ACCUM_MVMT; stml0xx_ms_data_buffer_write(ps_stml0xx, DT_ALGO_EVT, &buf[WAKE_IRQ_IDX_MODALITY_ACCUM_MVMT], 8); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending accum mvmt event"); } /* check for log messages */ if (irq_status & M_LOG_MSG) { memcpy(stat_string, &buf[WAKE_IRQ_IDX_LOG_MSG], LOG_MSG_SIZE); stat_string[LOG_MSG_SIZE] = 0; dev_err(&stml0xx_misc_data->spi->dev, "sensorhub : %s", stat_string); } if (irq_status & M_INIT_COMPLETE) { /* set the init complete register, */ /* to let the hub know it was received */ buf[0] = 0x01; err = stml0xx_spi_send_write_reg(INIT_COMPLETE_REG, buf, 1); queue_work(ps_stml0xx->irq_work_queue, &ps_stml0xx->initialize_work); dev_err(&stml0xx_misc_data->spi->dev, "Sensor Hub reports reset"); stml0xx_g_booted = 1; } /* check for a reset request */ if (irq_status & M_HUB_RESET) { unsigned char status = 0x01; stml0xx_as_data_buffer_write(ps_stml0xx, DT_RESET, &status, 1, 0, stm_ws->ts_ns); stml0xx_reset(stml0xx_misc_data->pdata); dev_err(&stml0xx_misc_data->spi->dev, "STML0XX requested a reset"); } EXIT: stml0xx_sleep(ps_stml0xx); EXIT_NO_WAKE: mutex_unlock(&ps_stml0xx->lock); kfree(stm_ws); }
void stml0xx_irq_work_func(struct work_struct *work) { int err; u32 irq_status; struct stml0xx_work_struct *stm_ws = (struct stml0xx_work_struct *)work; struct stml0xx_data *ps_stml0xx = stml0xx_misc_data; unsigned char buf[SPI_MSG_SIZE]; dev_dbg(&stml0xx_misc_data->spi->dev, "stml0xx_irq_work_func"); mutex_lock(&ps_stml0xx->lock); stml0xx_wake(ps_stml0xx); if (!stml0xx_g_booted) goto EXIT; if (ps_stml0xx->is_suspended) goto EXIT; err = stml0xx_spi_read_msg_data(SPI_MSG_TYPE_READ_IRQ_DATA, buf, SPI_RX_PAYLOAD_LEN, RESET_ALLOWED); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading from stml0xx failed"); goto EXIT; } irq_status = (buf[IRQ_IDX_STATUS_HI] << 16) | (buf[IRQ_IDX_STATUS_MED] << 8) | buf[IRQ_IDX_STATUS_LO]; if (irq_status & M_ACCEL) { int head = 0; int tail = 0; int first_accel_sample = 0; uint64_t ts_ns = 0; unsigned char *data_buf = 0; unsigned char *accel_buf = 0; uint8_t delay_ms = 0; data_buf = &buf[IRQ_IDX_ACCEL1]; ts_ns = stm_ws->ts_ns; head = data_buf[28]; tail = data_buf[32]; for ( first_accel_sample = 1, accel_buf = data_buf + 7*tail; tail != head; tail = (tail + 1) % 4, accel_buf = data_buf + 7*tail) { delay_ms = accel_buf[6]; if (first_accel_sample) first_accel_sample = 0; else ts_ns += delay_ms * 1000000LL; stml0xx_as_data_buffer_write( ps_stml0xx, DT_ACCEL, accel_buf, 6, 0, ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending acc(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ACCEL_RD_X, accel_buf), STM16_TO_HOST(ACCEL_RD_Y, accel_buf), STM16_TO_HOST(ACCEL_RD_Z, accel_buf)); } } if (irq_status & M_ACCEL2) { stml0xx_as_data_buffer_write(ps_stml0xx, DT_ACCEL2, &buf[IRQ_IDX_ACCEL2], 6, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending acc2(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ACCEL_RD_X, &buf[IRQ_IDX_ACCEL2]), STM16_TO_HOST(ACCEL_RD_Y, &buf[IRQ_IDX_ACCEL2]), STM16_TO_HOST(ACCEL_RD_Z, &buf[IRQ_IDX_ACCEL2])); } if (irq_status & M_ALS) { stml0xx_as_data_buffer_write( ps_stml0xx, DT_ALS, &buf[IRQ_IDX_ALS], 2, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending ALS %d", STM16_TO_HOST(ALS_VALUE, &buf[IRQ_IDX_ALS])); } if (irq_status & M_DISP_ROTATE) { stml0xx_as_data_buffer_write(ps_stml0xx, DT_DISP_ROTATE, &buf[IRQ_IDX_DISP_ROTATE], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending disp_rotate(x)value: %d", buf[IRQ_IDX_DISP_ROTATE]); } if (irq_status & M_DISP_BRIGHTNESS) { stml0xx_as_data_buffer_write(ps_stml0xx, DT_DISP_BRIGHT, &buf[IRQ_IDX_DISP_BRIGHTNESS], 1, 0, stm_ws->ts_ns); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Display Brightness %d", buf[IRQ_IDX_DISP_BRIGHTNESS]); } EXIT: kfree((void *)stm_ws); stml0xx_sleep(ps_stml0xx); /* For now HAE needs events even if the activity is still */ mutex_unlock(&ps_stml0xx->lock); }
void stm401_irq_work_func(struct work_struct *work) { int err; u32 irq_status; struct stm401_data *ps_stm401 = container_of(work, struct stm401_data, irq_work); dev_dbg(&ps_stm401->client->dev, "stm401_irq_work_func\n"); mutex_lock(&ps_stm401->lock); /* read interrupt mask register */ stm401_cmdbuff[0] = INTERRUPT_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 3); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n"); goto EXIT; } irq_status = (stm401_readbuff[IRQ_NOWAKE_HI] << 16) | (stm401_readbuff[IRQ_NOWAKE_MED] << 8) | stm401_readbuff[IRQ_NOWAKE_LO]; if (irq_status & M_ACCEL) { /* read accelerometer values from STM401 */ stm401_cmdbuff[0] = ACCEL_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 6); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Accel from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_ACCEL, stm401_readbuff, 6, 0); dev_dbg(&ps_stm401->client->dev, "Sending acc(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(ACCEL_RD_X), STM16_TO_HOST(ACCEL_RD_Y), STM16_TO_HOST(ACCEL_RD_Z)); } if (irq_status & M_LIN_ACCEL) { /* read linear accelerometer values from STM401 */ stm401_cmdbuff[0] = LIN_ACCEL_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 6); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Linear Accel from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_LIN_ACCEL, stm401_readbuff, 6, 0); dev_dbg(&ps_stm401->client->dev, "Sending lin_acc(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(ACCEL_RD_X), STM16_TO_HOST(ACCEL_RD_Y), STM16_TO_HOST(ACCEL_RD_Z)); } if (irq_status & M_ECOMPASS) { unsigned char status; /*Read orientation values */ stm401_cmdbuff[0] = MAG_HX; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 13); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Ecompass failed\n"); goto EXIT; } status = stm401_readbuff[COMPASS_STATUS]; stm401_as_data_buffer_write(ps_stm401, DT_MAG, stm401_readbuff, 6, status); dev_dbg(&ps_stm401->client->dev, "Sending mag(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(MAG_X), STM16_TO_HOST(MAG_Y), STM16_TO_HOST(MAG_Z)); stm401_as_data_buffer_write(ps_stm401, DT_ORIENT, stm401_readbuff + 6, 6, status); dev_dbg(&ps_stm401->client->dev, "Sending orient(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(ORIENT_X), STM16_TO_HOST(ORIENT_Y), STM16_TO_HOST(ORIENT_Z)); } if (irq_status & M_GYRO) { stm401_cmdbuff[0] = GYRO_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 6); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Gyroscope failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_GYRO, stm401_readbuff, 6, 0); dev_dbg(&ps_stm401->client->dev, "Sending gyro(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(GYRO_RD_X), STM16_TO_HOST(GYRO_RD_Y), STM16_TO_HOST(GYRO_RD_Z)); } /*MODIFIED UNCALIBRATED GYRO*/ if (irq_status & M_UNCALIB_GYRO) { stm401_cmdbuff[0] = UNCALIB_GYRO_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 12); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Gyroscope failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_UNCALIB_GYRO, stm401_readbuff, 12, 0); dev_dbg(&ps_stm401->client->dev, "Sending Gyro uncalib(x,y,z)values:%d,%d,%d;%d,%d,%d\n", STM16_TO_HOST(GYRO_RD_X), STM16_TO_HOST(GYRO_RD_Y), STM16_TO_HOST(GYRO_RD_Z), STM16_TO_HOST(GYRO_UNCALIB_X), STM16_TO_HOST(GYRO_UNCALIB_Y), STM16_TO_HOST(GYRO_UNCALIB_Z)); } if (irq_status & M_UNCALIB_MAG) { stm401_cmdbuff[0] = UNCALIB_MAG_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 12); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Gyroscope failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_UNCALIB_MAG, stm401_readbuff, 12, 0); dev_dbg(&ps_stm401->client->dev, "Sending Gyro uncalib(x,y,z)values:%d,%d,%d;%d,%d,%d\n", STM16_TO_HOST(MAG_X), STM16_TO_HOST(MAG_Y), STM16_TO_HOST(MAG_Z), STM16_TO_HOST(MAG_UNCALIB_X), STM16_TO_HOST(MAG_UNCALIB_Y), STM16_TO_HOST(MAG_UNCALIB_Z)); } if (irq_status & M_STEP_COUNTER) { stm401_cmdbuff[0] = STEP_COUNTER; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 8); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading step counter failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_STEP_COUNTER, stm401_readbuff, 8, 0); dev_dbg(&ps_stm401->client->dev, "Sending step counter %X %X %X %X\n", STM16_TO_HOST(STEP64_DATA), STM16_TO_HOST(STEP32_DATA), STM16_TO_HOST(STEP16_DATA), STM16_TO_HOST(STEP8_DATA)); } if (irq_status & M_STEP_DETECTOR) { unsigned short detected_steps = 0; stm401_cmdbuff[0] = STEP_DETECTOR; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading step detector failed\n"); goto EXIT; } detected_steps = stm401_readbuff[STEP_DETECT]; while (detected_steps-- != 0) { stm401_as_data_buffer_write(ps_stm401, DT_STEP_DETECTOR, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending step detector\n"); } } if (irq_status & M_ALS) { stm401_cmdbuff[0] = ALS_LUX; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading ALS from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_ALS, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "Sending ALS %d\n", STM16_TO_HOST(ALS_VALUE)); } if (irq_status & M_TEMPERATURE) { /*Read temperature value */ stm401_cmdbuff[0] = TEMPERATURE_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Temperature failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_TEMP, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "Sending temp(x)value:%d\n", STM16_TO_HOST(TEMP_VALUE)); } if (irq_status & M_PRESSURE) { /*Read pressure value */ stm401_cmdbuff[0] = CURRENT_PRESSURE; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 4); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Pressure failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_PRESSURE, stm401_readbuff, 4, 0); dev_dbg(&ps_stm401->client->dev, "Sending pressure %d\n", STM32_TO_HOST(PRESSURE_VALUE)); } if (irq_status & M_GRAVITY) { /* read gravity values from STM401 */ stm401_cmdbuff[0] = GRAVITY_X; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 6); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Gravity from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_GRAVITY, stm401_readbuff, 6, 0); dev_dbg(&ps_stm401->client->dev, "Sending gravity(x,y,z)values:x=%d,y=%d,z=%d\n", STM16_TO_HOST(GRAV_X), STM16_TO_HOST(GRAV_Y), STM16_TO_HOST(GRAV_Z)); } if (irq_status & M_DISP_ROTATE) { /*Read Display Rotate value */ stm401_cmdbuff[0] = DISP_ROTATE_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading disp_rotate failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_DISP_ROTATE, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending disp_rotate(x)value: %d\n", stm401_readbuff[DISP_VALUE]); } if (irq_status & M_DISP_BRIGHTNESS) { stm401_cmdbuff[0] = DISPLAY_BRIGHTNESS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Display Brightness failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_DISP_BRIGHT, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Display Brightness %d\n", stm401_readbuff[DISP_VALUE]); } if (irq_status & M_IR_GESTURE) { err = stm401_process_ir_gesture(ps_stm401); if (err < 0) goto EXIT; } if (irq_status & M_IR_RAW) { stm401_cmdbuff[0] = IR_RAW; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_IR_SZ_RAW); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading IR data failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_IR_RAW, stm401_readbuff, STM401_IR_SZ_RAW, 0); dev_dbg(&ps_stm401->client->dev, "Sending raw IR data\n"); } EXIT: /* For now HAE needs events even if the activity is still */ mutex_unlock(&ps_stm401->lock); }
void stm401_irq_wake_work_func(struct work_struct *work) { int err; unsigned short irq_status; u32 irq2_status; uint8_t irq3_status; struct stm401_data *ps_stm401 = container_of(work, struct stm401_data, irq_wake_work); dev_dbg(&ps_stm401->client->dev, "stm401_irq_wake_work_func\n"); mutex_lock(&ps_stm401->lock); if (ps_stm401->mode == BOOTMODE) goto EXIT_NO_WAKE; /* This is to handle the case of receiving an interrupt after suspend_late, but before interrupts were globally disabled. If this is the case, interrupts might be disabled now, so we cannot handle this at this time. suspend_noirq will return BUSY if this happens so that we can handle these interrupts. */ if (ps_stm401->ignore_wakeable_interrupts) { dev_info(&ps_stm401->client->dev, "Deferring interrupt work\n"); ps_stm401->ignored_interrupts++; goto EXIT_NO_WAKE; } stm401_wake(ps_stm401); /* read interrupt mask register */ stm401_cmdbuff[0] = WAKESENSOR_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n"); goto EXIT; } irq_status = (stm401_readbuff[IRQ_WAKE_MED] << 8) | stm401_readbuff[IRQ_WAKE_LO]; /* read algorithm interrupt status register */ stm401_cmdbuff[0] = ALGO_INT_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 3); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm401 failed\n"); goto EXIT; } irq2_status = (stm401_readbuff[IRQ_WAKE_HI] << 16) | (stm401_readbuff[IRQ_WAKE_MED] << 8) | stm401_readbuff[IRQ_WAKE_LO]; /* read generic interrupt register */ stm401_cmdbuff[0] = GENERIC_INT_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading from stm failed\n"); goto EXIT; } irq3_status = stm401_readbuff[0]; if (ps_stm401->qw_irq_status) { irq_status |= ps_stm401->qw_irq_status; ps_stm401->qw_irq_status = 0; } /* First, check for error messages */ if (irq_status & M_LOG_MSG) { stm401_cmdbuff[0] = ERROR_STATUS; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, ESR_SIZE); if (err >= 0) { memcpy(stat_string, stm401_readbuff, ESR_SIZE); stat_string[ESR_SIZE] = 0; dev_err(&ps_stm401->client->dev, "STM401 Error: %s\n", stat_string); } else dev_err(&ps_stm401->client->dev, "Failed to read error message %d\n", err); } /* Second, check for a reset request */ if (irq_status & M_HUB_RESET) { unsigned char status; if (strnstr(stat_string, "modality", ESR_SIZE)) status = 0x01; else if (strnstr(stat_string, "Algo", ESR_SIZE)) status = 0x02; else if (strnstr(stat_string, "Watchdog", ESR_SIZE)) status = 0x03; else status = 0x04; stm401_as_data_buffer_write(ps_stm401, DT_RESET, &status, 1, 0); stm401_reset_and_init(); dev_err(&ps_stm401->client->dev, "STM401 requested a reset\n"); goto EXIT; } /* Check all other status bits */ if (irq_status & M_DOCK) { int state; dev_err(&ps_stm401->client->dev, "Invalid M_DOCK bit set. irq_status = 0x%06x\n", irq_status); stm401_cmdbuff[0] = DOCK_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Dock state failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_DOCK, stm401_readbuff, 1, 0); state = stm401_readbuff[DOCK_STATE]; if (ps_stm401->dsdev.dev != NULL) switch_set_state(&ps_stm401->dsdev, state); if (ps_stm401->edsdev.dev != NULL) switch_set_state(&ps_stm401->edsdev, state); dev_dbg(&ps_stm401->client->dev, "Dock status:%d\n", state); } if (irq_status & M_PROXIMITY) { stm401_cmdbuff[0] = PROXIMITY; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading prox from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_PROX, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Proximity distance %d\n", stm401_readbuff[PROX_DISTANCE]); } if (irq_status & M_TOUCH) { if (stm401_display_handle_touch_locked(ps_stm401) < 0) goto EXIT; } if (irq_status & M_COVER) { int state; stm401_cmdbuff[0] = COVER_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading Cover state failed\n"); goto EXIT; } state = stm401_readbuff[COVER_STATE]; if (state > 0) state = 1; input_report_switch(ps_stm401->input_dev, SW_LID, state); input_sync(ps_stm401->input_dev); dev_dbg(&ps_stm401->client->dev, "Cover status: %d\n", state); } if (irq_status & M_QUICKPEEK) { if (stm401_display_handle_quickpeek_locked(ps_stm401, irq_status == M_QUICKPEEK) < 0) goto EXIT; } if (irq_status & M_FLATUP) { stm401_cmdbuff[0] = FLAT_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading flat data from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_FLAT_UP, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Flat up %d\n", stm401_readbuff[FLAT_UP]); } if (irq_status & M_FLATDOWN) { stm401_cmdbuff[0] = FLAT_DATA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading flat data from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_FLAT_DOWN, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Flat down %d\n", stm401_readbuff[FLAT_DOWN]); } if (irq_status & M_STOWED) { stm401_cmdbuff[0] = STOWED; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading stowed from stm401 failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_STOWED, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending Stowed status %d\n", stm401_readbuff[STOWED]); } if (irq_status & M_CAMERA_ACT) { stm401_cmdbuff[0] = CAMERA; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading camera data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_CAMERA_ACT, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "Sending Camera: %d\n", STM16_TO_HOST(CAMERA_VALUE)); input_report_key(ps_stm401->input_dev, KEY_CAMERA, 1); input_report_key(ps_stm401->input_dev, KEY_CAMERA, 0); input_sync(ps_stm401->input_dev); dev_dbg(&ps_stm401->client->dev, "Report camkey toggle\n"); } if (irq_status & M_NFC) { stm401_cmdbuff[0] = NFC; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 1); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading nfc data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_NFC, stm401_readbuff, 1, 0); dev_dbg(&ps_stm401->client->dev, "Sending NFC value: %d\n", stm401_readbuff[NFC_VALUE]); } if (irq_status & M_SIM) { stm401_cmdbuff[0] = SIM; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading sig_motion data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_SIM, stm401_readbuff, 2, 0); /* This is one shot sensor */ stm401_g_wake_sensor_state &= (~M_SIM); dev_dbg(&ps_stm401->client->dev, "Sending SIM Value=%d\n", STM16_TO_HOST(SIM_DATA)); } if (irq_status & M_CHOPCHOP) { stm401_cmdbuff[0] = CHOPCHOP; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, 2); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading chopchop data from stm failed\n"); goto EXIT; } stm401_as_data_buffer_write(ps_stm401, DT_CHOPCHOP, stm401_readbuff, 2, 0); dev_dbg(&ps_stm401->client->dev, "ChopChop triggered. Gyro aborts=%d\n", STM16_TO_HOST(CHOPCHOP_DATA)); } if (irq2_status & M_MMOVEME) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STM401_CLIENT_MASK) | M_MMOVEME; stm401_ms_data_buffer_write(ps_stm401, DT_MMMOVE, &status, 1); dev_dbg(&ps_stm401->client->dev, "Sending meaningful movement event\n"); } if (irq2_status & M_NOMMOVE) { unsigned char status; /* Client recieving action will be upper 2 most significant */ /* bits of the least significant byte of status. */ status = (irq2_status & STM401_CLIENT_MASK) | M_NOMMOVE; stm401_ms_data_buffer_write(ps_stm401, DT_NOMOVE, &status, 1); dev_dbg(&ps_stm401->client->dev, "Sending no meaningful movement event\n"); } if (irq2_status & M_ALGO_MODALITY) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_MODALITY].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading modality event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_MODALITY; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending modality event\n"); } if (irq2_status & M_ALGO_ORIENTATION) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ORIENTATION].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading orientation event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ORIENTATION; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending orientation event\n"); } if (irq2_status & M_ALGO_STOWED) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_STOWED].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_TRANSITION); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading stowed event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_STOWED; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending stowed event\n"); } if (irq2_status & M_ALGO_ACCUM_MODALITY) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ACCUM_MODALITY] .evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_ACCUM_STATE); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading accum modality event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MODALITY; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending accum modality event\n"); } if (irq2_status & M_ALGO_ACCUM_MVMT) { stm401_cmdbuff[0] = stm401_algo_info[STM401_IDX_ACCUM_MVMT].evt_register; err = stm401_i2c_write_read(ps_stm401, stm401_cmdbuff, 1, STM401_EVT_SZ_ACCUM_MVMT); if (err < 0) { dev_err(&ps_stm401->client->dev, "Reading accum mvmt event failed\n"); goto EXIT; } stm401_readbuff[ALGO_TYPE] = STM401_IDX_ACCUM_MVMT; stm401_ms_data_buffer_write(ps_stm401, DT_ALGO_EVT, stm401_readbuff, 8); dev_dbg(&ps_stm401->client->dev, "Sending accum mvmt event\n"); } if (irq2_status & M_IR_WAKE_GESTURE) { err = stm401_process_ir_gesture(ps_stm401); if (err < 0) goto EXIT; } if (irq3_status & M_GENERIC_INTRPT) { dev_err(&ps_stm401->client->dev, "Invalid M_GENERIC_INTRPT bit set. irq_status = 0x%06x\n", irq_status); /* x (data1) : irq3_status */ stm401_ms_data_buffer_write(ps_stm401, DT_GENERIC_INT, &irq3_status, 1); dev_dbg(&ps_stm401->client->dev, "Sending generic interrupt event:%d\n", irq3_status); } EXIT: stm401_sleep(ps_stm401); EXIT_NO_WAKE: mutex_unlock(&ps_stm401->lock); }
void stml0xx_irq_work_func(struct work_struct *work) { int err; u32 irq_status; struct stml0xx_data *ps_stml0xx = stml0xx_misc_data; unsigned char buf[SPI_MSG_SIZE]; dev_dbg(&stml0xx_misc_data->spi->dev, "stml0xx_irq_work_func"); mutex_lock(&ps_stml0xx->lock); stml0xx_wake(ps_stml0xx); if (ps_stml0xx->mode == BOOTMODE) goto EXIT; if (ps_stml0xx->is_suspended) goto EXIT; /* read interrupt mask register */ err = stml0xx_spi_send_read_reg(INTERRUPT_STATUS, buf, 3); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading from stml0xx failed"); goto EXIT; } irq_status = (buf[IRQ_NOWAKE_HI] << 16) | (buf[IRQ_NOWAKE_MED] << 8) | buf[IRQ_NOWAKE_LO]; if (irq_status & M_ACCEL) { /* read accelerometer values from STML0XX */ err = stml0xx_spi_send_read_reg(ACCEL_X, buf, 6); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Accel from stml0xx failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_ACCEL, buf, 6, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending acc(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ACCEL_RD_X), STM16_TO_HOST(ACCEL_RD_Y), STM16_TO_HOST(ACCEL_RD_Z)); } if (irq_status & M_ACCEL2) { /* read 2nd accelerometer values from STML0XX */ err = stml0xx_spi_send_read_reg(ACCEL2_X, buf, 6); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading 2nd Accel from stml0xx failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_ACCEL2, buf, 6, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending acc2(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ACCEL_RD_X), STM16_TO_HOST(ACCEL_RD_Y), STM16_TO_HOST(ACCEL_RD_Z)); } if (irq_status & M_LIN_ACCEL) { dev_err(&stml0xx_misc_data->spi->dev, "Invalid M_LIN_ACCEL bit set. irq_status = 0x%06x", irq_status); /* read linear accelerometer values from STML0XX */ err = stml0xx_spi_send_read_reg(LIN_ACCEL_X, buf, 6); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Linear Accel from stml0xx failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_LIN_ACCEL, buf, 6, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending lin_acc(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ACCEL_RD_X), STM16_TO_HOST(ACCEL_RD_Y), STM16_TO_HOST(ACCEL_RD_Z)); } if (irq_status & M_ECOMPASS) { unsigned char status; /*Read orientation values */ err = stml0xx_spi_send_read_reg(MAG_HX, buf, 13); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Ecompass failed"); goto EXIT; } status = buf[COMPASS_STATUS]; stml0xx_as_data_buffer_write(ps_stml0xx, DT_MAG, buf, 6, status); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending mag(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(MAG_X), STM16_TO_HOST(MAG_Y), STM16_TO_HOST(MAG_Z)); stml0xx_as_data_buffer_write(ps_stml0xx, DT_ORIENT, buf + 6, 6, status); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending orient(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(ORIENT_X), STM16_TO_HOST(ORIENT_Y), STM16_TO_HOST(ORIENT_Z)); } if (irq_status & M_GYRO) { err = stml0xx_spi_send_read_reg(GYRO_X, buf, 6); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Gyroscope failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_GYRO, buf, 6, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending gyro(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(GYRO_RD_X), STM16_TO_HOST(GYRO_RD_Y), STM16_TO_HOST(GYRO_RD_Z)); } /*MODIFIED UNCALIBRATED GYRO */ if (irq_status & M_UNCALIB_GYRO) { err = stml0xx_spi_send_read_reg(UNCALIB_GYRO_X, buf, 12); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Gyroscope failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_UNCALIB_GYRO, buf, 12, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Gyro uncalib(x,y,z)values:%d,%d,%d;%d,%d,%d", STM16_TO_HOST(GYRO_RD_X), STM16_TO_HOST(GYRO_RD_Y), STM16_TO_HOST(GYRO_RD_Z), STM16_TO_HOST(GYRO_UNCALIB_X), STM16_TO_HOST(GYRO_UNCALIB_Y), STM16_TO_HOST(GYRO_UNCALIB_Z)); } if (irq_status & M_UNCALIB_MAG) { err = stml0xx_spi_send_read_reg(UNCALIB_MAG_X, buf, 12); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Gyroscope failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_UNCALIB_MAG, buf, 12, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Gyro uncalib(x,y,z)values:%d,%d,%d;%d,%d,%d", STM16_TO_HOST(MAG_X), STM16_TO_HOST(MAG_Y), STM16_TO_HOST(MAG_Z), STM16_TO_HOST(MAG_UNCALIB_X), STM16_TO_HOST(MAG_UNCALIB_Y), STM16_TO_HOST(MAG_UNCALIB_Z)); } if (irq_status & M_ALS) { err = stml0xx_spi_send_read_reg(ALS_LUX, buf, 2); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading ALS from stml0xx failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_ALS, buf, 2, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending ALS %d", STM16_TO_HOST(ALS_VALUE)); } if (irq_status & M_TEMPERATURE) { /* Read temperature value */ err = stml0xx_spi_send_read_reg(TEMPERATURE_DATA, buf, 2); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Temperature failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_TEMP, buf, 2, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending temp(x)value:%d", STM16_TO_HOST(TEMP_VALUE)); } if (irq_status & M_PRESSURE) { dev_err(&stml0xx_misc_data->spi->dev, "Invalid M_PRESSURE bit set. irq_status = 0x%06x", irq_status); /* Read pressure value */ err = stml0xx_spi_send_read_reg(CURRENT_PRESSURE, buf, 4); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Pressure failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_PRESSURE, buf, 4, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending pressure %d", STM32_TO_HOST(PRESSURE_VALUE)); } if (irq_status & M_GRAVITY) { dev_err(&stml0xx_misc_data->spi->dev, "Invalid M_GRAVITY bit set. irq_status = 0x%06x", irq_status); /* read gravity values from STML0XX */ err = stml0xx_spi_send_read_reg(GRAVITY_X, buf, 6); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Gravity from stml0xx failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_GRAVITY, buf, 6, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending gravity(x,y,z)values:x=%d,y=%d,z=%d", STM16_TO_HOST(GRAV_X), STM16_TO_HOST(GRAV_Y), STM16_TO_HOST(GRAV_Z)); } if (irq_status & M_DISP_ROTATE) { /* Read Display Rotate value */ err = stml0xx_spi_send_read_reg(DISP_ROTATE_DATA, buf, 1); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading disp_rotate failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_DISP_ROTATE, buf, 1, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending disp_rotate(x)value: %d", buf[DISP_VALUE]); } if (irq_status & M_DISP_BRIGHTNESS) { err = stml0xx_spi_send_read_reg(DISPLAY_BRIGHTNESS, buf, 1); if (err < 0) { dev_err(&stml0xx_misc_data->spi->dev, "Reading Display Brightness failed"); goto EXIT; } stml0xx_as_data_buffer_write(ps_stml0xx, DT_DISP_BRIGHT, buf, 1, 0); dev_dbg(&stml0xx_misc_data->spi->dev, "Sending Display Brightness %d", buf[DISP_VALUE]); } EXIT: stml0xx_sleep(ps_stml0xx); /* For now HAE needs events even if the activity is still */ mutex_unlock(&ps_stml0xx->lock); wake_unlock(&ps_stml0xx->wakelock); }