static void cma3000_read_report_data(struct cma3000_accl_data *data) { int datax, datay, dataz; u8 ctrl, mode, range, intr_status; mutex_lock(&data->mutex); intr_status = cma3000_read(data, CMA3000_INTSTATUS, "interrupt status"); if (intr_status < 0) { pr_info("%s:No interrupt from the device\n", __func__); goto not_from_device; } /* Check if free fall is detected, report immediately */ if (intr_status & CMA3000_INTSTATUS_FFDET) { if (accl_debug) pr_info("%s:Free fall\n", __func__); input_report_abs(data->input_dev, ABS_MISC, 1); input_sync(data->input_dev); } else { input_report_abs(data->input_dev, ABS_MISC, 0); } datax = cma3000_read(data, CMA3000_DOUTX, "X"); datay = cma3000_read(data, CMA3000_DOUTY, "Y"); dataz = cma3000_read(data, CMA3000_DOUTZ, "Z"); if (accl_debug) pr_info("%s:Raw x= %d, y= %d, z= %d\n", __func__, datax, datay, dataz); ctrl = cma3000_read(data, CMA3000_CTRL, "ctrl"); mode = (ctrl & CMA3000_MODEMASK) >> 1; range = (ctrl & CMA3000_GRANGEMASK) >> 7; data->bit_to_mg = mode_to_mg[mode][range]; /* Interrupt not for this device */ if (data->bit_to_mg == 0) goto not_from_device; /* Decode register values to milli g */ decode_mg(data, &datax, &datay, &dataz); if (accl_debug) pr_info("%s:Reporting x= %d, y= %d, z= %d\n", __func__, datax, datay, dataz); input_report_abs(data->input_dev, ABS_X, datax); input_report_abs(data->input_dev, ABS_Y, datay); input_report_abs(data->input_dev, ABS_Z, dataz); input_sync(data->input_dev); not_from_device: mutex_unlock(&data->mutex); if (data->client->irq) enable_irq(data->client->irq); }
static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) { struct cma3000_accl_data *data = dev_id; int datax, datay, dataz; u8 ctrl, mode, range, intr_status; intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); if (intr_status < 0) return IRQ_NONE; /* Check if free fall is detected, report immediately */ if (intr_status & CMA3000_INTSTATUS_FFDET) { input_report_abs(data->input_dev, ABS_MISC, 1); input_sync(data->input_dev); } else { input_report_abs(data->input_dev, ABS_MISC, 0); } datax = CMA3000_READ(data, CMA3000_DOUTX, "X"); datay = CMA3000_READ(data, CMA3000_DOUTY, "Y"); dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z"); ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl"); mode = (ctrl & CMA3000_MODEMASK) >> 1; range = (ctrl & CMA3000_GRANGEMASK) >> 7; data->bit_to_mg = mode_to_mg[mode][range]; /* Interrupt not for this device */ if (data->bit_to_mg == 0) return IRQ_NONE; /* Decode register values to milli g */ decode_mg(data, &datax, &datay, &dataz); input_report_abs(data->input_dev, ABS_X, datax); input_report_abs(data->input_dev, ABS_Y, datay); input_report_abs(data->input_dev, ABS_Z, dataz); input_sync(data->input_dev); return IRQ_HANDLED; }