/** * * Synaptics Register Mapped Interface (RMI4) Function $11 support for 2D. * Copyright (c) 2007 - 2011, Synaptics Incorporated * */ /* * This file is licensed under the GPL2 license. * *############################################################################# * GPL * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * *############################################################################# */ #include #include #include #include #include #include #include #include #include #include "rmi.h" #include "rmi_drvr.h" #include "rmi_bus.h" #include "rmi_sensor.h" #include "rmi_function.h" #include "rmi_f19.h" struct f19_instance_data { struct rmi_F19_query *deviceInfo; struct rmi_F19_control *controlRegisters; bool *buttonDown; unsigned char buttonDataBufferSize; unsigned char *buttonDataBuffer; unsigned char *buttonMap; int fn19ControlRegisterSize; int fn19regCountForBitPerButton; int fn19btnUsageandfilterModeOffset; int fn19intEnableOffset; int fn19intEnableLen; int fn19singleBtnCtrlLen; int fn19singleBtnCtrlOffset; int fn19sensorMapCtrlOffset; int fn19sensorMapCtrlLen; int fn19singleBtnSensOffset; int fn19singleBtnSensLen; int fn19globalSensOffset; int fn19globalHystThreshOffset; }; static ssize_t rmi_f19_buttonCount_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t rmi_f19_buttonCount_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); DEVICE_ATTR(buttonCount, 0444, rmi_f19_buttonCount_show, rmi_f19_buttonCount_store); /* RO attr */ static ssize_t rmi_f19_buttonMap_show(struct device *dev, struct device_attribute *attr, char *buf); static ssize_t rmi_f19_buttonMap_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); DEVICE_ATTR(buttonMap, 0664, rmi_f19_buttonMap_show, rmi_f19_buttonMap_store); /* RW attr */ /* * There is no attention function for F19 - it is left NULL * in the function table so it is not called. * */ /* * This reads in a sample and reports the F19 source data to the * input subsystem. It is used for both polling and interrupt driven * operation. This is called a lot so don't put in any informational * printks since they will slow things way down! */ void FN_19_inthandler(struct rmi_function_info *rmifninfo, unsigned int assertedIRQs) { struct rmi_function_device *function_device; struct f19_instance_data *instanceData; int button; instanceData = (struct f19_instance_data *) rmifninfo->fndata; function_device = rmifninfo->function_device; /* Read the button data. */ if (rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.dataBaseAddr, instanceData->buttonDataBuffer, instanceData->buttonDataBufferSize)) { printk(KERN_ERR "%s: Failed to read button data registers.\n", __func__); return; } /* Generate events for buttons that change state. */ for (button = 0; button < instanceData->deviceInfo->buttonCount; button++) { int buttonReg; int buttonShift; bool buttonStatus; /* determine which data byte the button status is in */ buttonReg = button/4; /* bit shift to get button's status */ buttonShift = button % 8; buttonStatus = ((instanceData->buttonDataBuffer[buttonReg] >> buttonShift) & 0x01) != 0; /* if the button state changed from the last time report it and store the new state */ if (buttonStatus != instanceData->buttonDown[button]) { printk(KERN_DEBUG "%s: Button %d (code %d) -> %d.", __func__, button, instanceData->buttonMap[button], buttonStatus); /* Generate an event here. */ input_report_key(function_device->input, instanceData->buttonMap[button], buttonStatus); instanceData->buttonDown[button] = buttonStatus; } } input_sync(function_device->input); /* sync after groups of events */ } EXPORT_SYMBOL(FN_19_inthandler); int FN_19_config(struct rmi_function_info *rmifninfo) { int retval = 0; pr_debug("%s: RMI4 F19 config\n", __func__); /* TODO: Perform configuration. In particular, write any cached control * register values to the device. */ return retval; } EXPORT_SYMBOL(FN_19_config); /* Initialize any F19 specific params and settings - input * settings, device settings, etc. */ int FN_19_init(struct rmi_function_device *function_device) { int i, retval = 0; struct f19_instance_data *instance_data = function_device->rfi->fndata; struct rmi_f19_functiondata *functiondata = rmi_sensor_get_functiondata(function_device->sensor, RMI_F19_INDEX); printk(KERN_DEBUG "%s: RMI4 F19 init\n", __func__); if (functiondata) { if (functiondata->button_map) { if (functiondata->button_map->nbuttons != instance_data->deviceInfo->buttonCount) { printk(KERN_WARNING "%s: Platformdata button map size (%d) != number of buttons on device (%d) - ignored.", __func__, functiondata->button_map->nbuttons, instance_data->deviceInfo->buttonCount); } else if (!functiondata->button_map->map) { printk(KERN_WARNING "%s: Platformdata button map is missing!", __func__); } else { for (i = 0; i < functiondata->button_map->nbuttons; i++) instance_data->buttonMap[i] = functiondata->button_map->map[i]; } } } /* Set up any input events. */ set_bit(EV_SYN, function_device->input->evbit); set_bit(EV_KEY, function_device->input->evbit); /* set bits for each button...*/ for (i = 0; i < instance_data->deviceInfo->buttonCount; i++) { set_bit(instance_data->buttonMap[i], function_device->input->keybit); } printk(KERN_DEBUG "%s: Creating sysfs files.", __func__); retval = device_create_file(&function_device->dev, &dev_attr_buttonCount); if (retval) { printk(KERN_ERR "%s: Failed to create button count.", __func__); return retval; } retval = device_create_file(&function_device->dev, &dev_attr_buttonMap); if (retval) { printk(KERN_ERR "%s: Failed to create button map.", __func__); return retval; } return 0; } EXPORT_SYMBOL(FN_19_init); static int getControlRegisters(struct rmi_function_info *rmifninfo, struct rmi_function_descriptor *fndescr) { struct f19_instance_data *instanceData; unsigned char *fn19Control = NULL; int retval = 0; /* Get the instance data - it should have been allocated and stored in detect.*/ instanceData = rmifninfo->fndata; /* Check to make sure instanceData is really there before using.*/ if (!instanceData) { printk(KERN_ERR "%s: Error - instance data not initialized yet when getting fn19 control registers.\n", __func__); return -EINVAL; } /* Allocate memory for the control registers. */ instanceData->controlRegisters = kzalloc(sizeof(struct rmi_F19_control), GFP_KERNEL); if (!instanceData->controlRegisters) { printk(KERN_ERR "%s: Error allocating F19 control registers.\n", __func__); return -ENOMEM; } instanceData->fn19regCountForBitPerButton = (instanceData->deviceInfo->buttonCount + 7)/8; /* Need to compute the amount of data to read since it varies with the * number of buttons */ instanceData->fn19ControlRegisterSize = 1 /* 1 for filter mode and button usage bits */ + 2*instanceData->fn19regCountForBitPerButton /* interrupt enable bits and single button participation bits */ + 2*instanceData->deviceInfo->buttonCount /* sensormap registers + single button sensitivity registers */ + 2; /* 1 for global sensitivity adjust + 1 for global hysteresis threshold */ /* Allocate a temp memory buffer to read the control registers into */ fn19Control = kzalloc(instanceData->fn19ControlRegisterSize, GFP_KERNEL); if (!fn19Control) { printk(KERN_ERR "%s: Error allocating temp storage to read fn19 control info.\n", __func__); return -ENOMEM; } /* Grab a copy of the control registers. */ retval = rmi_read_multiple(rmifninfo->sensor, fndescr->controlBaseAddr, fn19Control, instanceData->fn19ControlRegisterSize); if (retval) { printk(KERN_ERR "%s: Failed to read F19 control registers.", __func__); return retval; } /* Copy over control registers data to the instance data */ instanceData->fn19btnUsageandfilterModeOffset = 0; instanceData->controlRegisters->buttonUsage = fn19Control[instanceData->fn19btnUsageandfilterModeOffset] & 0x3; instanceData->controlRegisters->filterMode = fn19Control[instanceData->fn19btnUsageandfilterModeOffset] & 0xc; /* Fill in interrupt enable registers */ instanceData->fn19intEnableOffset = 1; instanceData->fn19intEnableLen = instanceData->fn19regCountForBitPerButton; instanceData->controlRegisters->intEnableRegisters = kzalloc(instanceData->fn19intEnableLen, GFP_KERNEL); if (!instanceData->controlRegisters->intEnableRegisters) { printk(KERN_ERR "%s: Error allocating storage for interrupt enable control info.\n", __func__); return -ENOMEM; } memcpy(instanceData->controlRegisters->intEnableRegisters, &fn19Control[instanceData->fn19intEnableOffset], instanceData->fn19intEnableLen); /* Fill in single button control registers */ instanceData->fn19singleBtnCtrlOffset = instanceData->fn19intEnableOffset + instanceData->fn19intEnableLen; instanceData->fn19singleBtnCtrlLen = instanceData->fn19regCountForBitPerButton; instanceData->controlRegisters->singleButtonControl = kzalloc(instanceData->fn19singleBtnCtrlLen, GFP_KERNEL); if (!instanceData->controlRegisters->singleButtonControl) { printk(KERN_ERR "%s: Error allocating storage for single button participation control info.\n", __func__); return -ENOMEM; } memcpy(instanceData->controlRegisters->singleButtonControl, &fn19Control[instanceData->fn19singleBtnCtrlOffset], instanceData->fn19singleBtnCtrlLen); /* Fill in sensor map registers */ instanceData->fn19sensorMapCtrlOffset = instanceData->fn19singleBtnCtrlOffset + instanceData->fn19singleBtnCtrlLen; instanceData->fn19sensorMapCtrlLen = instanceData->deviceInfo->buttonCount; instanceData->controlRegisters->sensorMap = kzalloc(instanceData->fn19sensorMapCtrlLen, GFP_KERNEL); if (!instanceData->controlRegisters->sensorMap) { printk(KERN_ERR "%s: Error allocating storage for sensor map control info.\n", __func__); return -ENOMEM; } memcpy(instanceData->controlRegisters->sensorMap, &fn19Control[instanceData->fn19sensorMapCtrlOffset], instanceData->fn19sensorMapCtrlLen); /* Fill in single button sensitivity registers */ instanceData->fn19singleBtnSensOffset = instanceData->fn19sensorMapCtrlOffset + instanceData->fn19sensorMapCtrlLen; instanceData->fn19singleBtnSensLen = instanceData->deviceInfo->buttonCount; instanceData->controlRegisters->singleButtonSensitivity = kzalloc(instanceData->fn19singleBtnSensLen, GFP_KERNEL); if (!instanceData->controlRegisters->intEnableRegisters) { printk(KERN_ERR "%s: Error allocating storage for single button sensitivity control info.\n", __func__); return -ENOMEM; } memcpy(instanceData->controlRegisters->singleButtonSensitivity, &fn19Control[instanceData->fn19singleBtnSensOffset], instanceData->fn19singleBtnSensLen); /* Fill in global sensitivity adjustment and global hysteresis threshold values */ instanceData->fn19globalSensOffset = instanceData->fn19singleBtnSensOffset + instanceData->fn19singleBtnSensLen; instanceData->fn19globalHystThreshOffset = instanceData->fn19globalSensOffset + 1; instanceData->controlRegisters->globalSensitivityAdjustment = fn19Control[instanceData->fn19globalSensOffset] & 0x1f; instanceData->controlRegisters->globalHysteresisThreshold = fn19Control[instanceData->fn19globalHystThreshOffset] & 0x0f; /* Free up temp storage that held copy of control registers */ kfree(fn19Control); return 0; } int FN_19_detect(struct rmi_function_info *rmifninfo, struct rmi_function_descriptor *fndescr, unsigned int interruptCount) { unsigned char fn19queries[2]; int retval = 0; int i; struct f19_instance_data *instanceData; int fn19InterruptOffset; printk(KERN_DEBUG "%s: RMI4 F19 detect\n", __func__); instanceData = kzalloc(sizeof(struct f19_instance_data), GFP_KERNEL); if (!instanceData) { printk(KERN_ERR "%s: Error allocating F19 instance data.\n", __func__); return -ENOMEM; } instanceData->deviceInfo = kzalloc(sizeof(struct rmi_F19_query), GFP_KERNEL); if (!instanceData->deviceInfo) { printk(KERN_ERR "%s: Error allocating F19 device query.\n", __func__); return -ENOMEM; } rmifninfo->fndata = instanceData; /* Store addresses - used elsewhere to read data, * control, query, etc. */ rmifninfo->funcDescriptor.queryBaseAddr = fndescr->queryBaseAddr; rmifninfo->funcDescriptor.commandBaseAddr = fndescr->commandBaseAddr; rmifninfo->funcDescriptor.controlBaseAddr = fndescr->controlBaseAddr; rmifninfo->funcDescriptor.dataBaseAddr = fndescr->dataBaseAddr; rmifninfo->funcDescriptor.interruptSrcCnt = fndescr->interruptSrcCnt; rmifninfo->funcDescriptor.functionNum = fndescr->functionNum; rmifninfo->numSources = fndescr->interruptSrcCnt; /* need to get number of fingers supported, data size, etc. - to be used when getting data since the number of registers to read depends on the number of fingers supported and data size. */ retval = rmi_read_multiple(rmifninfo->sensor, fndescr->queryBaseAddr, fn19queries, sizeof(fn19queries)); if (retval) { printk(KERN_ERR "%s: RMI4 F19 detect: " "Could not read function query registers 0x%x\n", __func__, rmifninfo->funcDescriptor.queryBaseAddr); return retval; } /* Extract device data. */ instanceData->deviceInfo->configurable = fn19queries[0] & 0x01; instanceData->deviceInfo->hasSensitivityAdjust = fn19queries[0] & 0x02; instanceData->deviceInfo->hasHysteresisThreshold = fn19queries[0] & 0x04; instanceData->deviceInfo->buttonCount = fn19queries[1] & 0x01F; printk(KERN_DEBUG "%s: F19 device - %d buttons...", __func__, instanceData->deviceInfo->buttonCount); /* Need to get interrupt info to be used later when handling interrupts. */ rmifninfo->interruptRegister = interruptCount/8; /* loop through interrupts for each source in fn $11 and or in a bit to the interrupt mask for each. */ fn19InterruptOffset = interruptCount % 8; for (i = fn19InterruptOffset; i < ((fndescr->interruptSrcCnt & 0x7) + fn19InterruptOffset); i++) rmifninfo->interruptMask |= 1 << i; /* Figure out just how much data we'll need to read. */ instanceData->buttonDown = kcalloc(instanceData->deviceInfo->buttonCount, sizeof(bool), GFP_KERNEL); if (!instanceData->buttonDown) { printk(KERN_ERR "%s: Error allocating F19 button state buffer.\n", __func__); return -ENOMEM; } instanceData->buttonDataBufferSize = (instanceData->deviceInfo->buttonCount + 7) / 8; instanceData->buttonDataBuffer = kcalloc(instanceData->buttonDataBufferSize, sizeof(unsigned char), GFP_KERNEL); if (!instanceData->buttonDataBuffer) { printk(KERN_ERR "%s: Failed to allocate button data buffer.", __func__); return -ENOMEM; } instanceData->buttonMap = kcalloc(instanceData->deviceInfo->buttonCount, sizeof(unsigned char), GFP_KERNEL); if (!instanceData->buttonMap) { printk(KERN_ERR "%s: Error allocating F19 button map.\n", __func__); return -ENOMEM; } for (i = 0; i < instanceData->deviceInfo->buttonCount; i++) instanceData->buttonMap[i] = BTN_0 + i; /* default values */ /* Grab the control register info. */ retval = getControlRegisters(rmifninfo, fndescr); if (retval) { printk(KERN_ERR "%s: Error %d getting fn19 control register info.\n", __func__, retval); return retval; } return 0; } EXPORT_SYMBOL(FN_19_detect); static ssize_t rmi_f19_buttonCount_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rmi_function_device *fn = dev_get_drvdata(dev); struct f19_instance_data *instance_data = (struct f19_instance_data *)fn->rfi->fndata; return sprintf(buf, "%u\n", instance_data->deviceInfo->buttonCount); } static ssize_t rmi_f19_buttonCount_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { /* Not allowed. */ return -EPERM; } static ssize_t rmi_f19_buttonMap_show(struct device *dev, struct device_attribute *attr, char *buf) { struct rmi_function_device *fn = dev_get_drvdata(dev); struct f19_instance_data *instance_data = (struct f19_instance_data *)fn->rfi->fndata; int i, len, totalLen = 0; /* loop through each button map value and copy it's string representation into buf */ for (i = 0; i < instance_data->deviceInfo->buttonCount; i++) { /* get next button mapping value and write it to buf */ len = sprintf(buf, "%u ", instance_data->buttonMap[i]); /* bump up ptr to next location in buf if the sprintf was valid */ if (len > 0) { buf += len; totalLen += len; } } return totalLen; } static ssize_t rmi_f19_buttonMap_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct rmi_function_device *fn = dev_get_drvdata(dev); struct f19_instance_data *instance_data = (struct f19_instance_data *)fn->rfi->fndata; unsigned int button; int i; int retval = count; int buttonCount = 0; unsigned char *tmpButtonMap; /* Do validation on the button map data passed in. */ /* Store button mappings into a temp buffer and then verify button count and data prior to clearing out old button mappings and storing the new ones. */ tmpButtonMap = kzalloc(instance_data->deviceInfo->buttonCount, GFP_KERNEL); if (!tmpButtonMap) { printk(KERN_ERR "%s: Error allocating temp button map.\n", __func__); return -ENOMEM; } for (i = 0; i < instance_data->deviceInfo->buttonCount && *buf != 0; i++) { /* get next button mapping value and store and bump up to point to next item in buf */ sscanf(buf, "%u", &button); /* Make sure the key is a valid key */ if (button > KEY_MAX) { printk(KERN_ERR "%s: Error - button map for button %d is not a valid value 0x%x.\n", __func__, i, button); retval = -EINVAL; goto err_ret; } tmpButtonMap[i] = button; buttonCount++; /* bump up buf to point to next item to read */ while (*buf != 0) { buf++; if (*(buf-1) == ' ') break; } } /* Make sure the button count matches */ if (buttonCount != instance_data->deviceInfo->buttonCount) { printk(KERN_ERR "%s: Error - button map count of %d doesn't match device button count of %d.\n" , __func__, buttonCount, instance_data->deviceInfo->buttonCount); retval = -EINVAL; goto err_ret; } /* Clear out old buttonMap data */ memset(instance_data->buttonMap, 0, buttonCount); /* Loop through the temp buffer and copy the button event and set the key bit for the new mapping. */ for (i = 0; i < buttonCount; i++) { instance_data->buttonMap[i] = tmpButtonMap[1]; set_bit(instance_data->buttonMap[i], fn->input->keybit); } err_ret: kfree(tmpButtonMap); return retval; }