void FN_34_inthandler(struct rmi_function_info *rmifninfo, unsigned int assertedIRQs) { unsigned int status; struct rmi_fn_34_data *fn34data = (struct rmi_fn_34_data *)rmifninfo->fndata; /* */ /* */ if (rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.dataBaseAddr+3, (unsigned char *)&status, 1)) { printk(KERN_ERR "%s : Could not read status from 0x%x\n", __func__, rmifninfo->funcDescriptor.dataBaseAddr+3); status = 0xff; /* */ } /* */ fn34data->status = status & 0xf0; /* */ }
/*. * The interrupt handler for Fn $01 doesn't do anything (for now). */ void FN_01_inthandler(struct rmi_function_info *rmifninfo, unsigned int assertedIRQs) { struct f01_instance_data *instanceData = (struct f01_instance_data *) rmifninfo->fndata; printk(KERN_DEBUG "%s: Read device status.", __func__); if (rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.dataBaseAddr, &instanceData->dataRegisters->deviceStatus, 1)) { printk(KERN_ERR "%s : Could not read F01 device status.\n", __func__); } printk(KERN_INFO "%s: read device status register. Value 0x%02X.", __func__, instanceData->dataRegisters->deviceStatus); if (instanceData->dataRegisters->deviceStatus & F01_UNCONFIGURED) { printk(KERN_INFO "%s: ++++ Device reset detected.", __func__); /* TODO: Handle device reset appropriately. */ } }
/* * This reads in the function $01 source data. * */ void FN_01_attention(struct rmi_function_info *rmifninfo) { struct f01_instance_data *instanceData = (struct f01_instance_data *) rmifninfo->fndata; /* TODO: Compute size to read and number of IRQ registers to processors * dynamically. See comments in rmi.h. */ if (rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.dataBaseAddr+1, instanceData->dataRegisters->irqs, 1)) { printk(KERN_ERR "%s : Could not read interrupt status registers at 0x%02x\n", __func__, rmifninfo->funcDescriptor.dataBaseAddr); return; } if (instanceData->dataRegisters->irqs[0] & instanceData->controlRegisters->interruptEnable[0]) { // printk(KERN_INFO "%s: ++++ IRQs == 0x%02X", __func__, instanceData->dataRegisters->irqs[0]); /* call down to the sensors irq dispatcher to dispatch all enabled IRQs */ rmifninfo->sensor->dispatchIRQs(rmifninfo->sensor, instanceData->dataRegisters->irqs[0]); } }
static ssize_t rmi_fn_34_data_read(struct file * filp, struct kobject *kobj, struct bin_attribute *attributes, char *buf, loff_t pos, size_t count) { struct device *dev = container_of(kobj, struct device, kobj); struct rmi_function_device *fn = dev_get_drvdata(dev); int error; /* */ /* */ /* */ /* */ error = rmi_read_multiple(fn->sensor, fn->function->functionDataBaseAddr+pos, (unsigned char *)buf, count); if (error) { printk(KERN_ERR "%s : Could not read data from 0x%llx\n", __func__, fn->function->functionDataBaseAddr+pos); return error; } return count; }
int FN_01_detect(struct rmi_function_info *rmifninfo, struct rmi_function_descriptor *fndescr, unsigned int interruptCount) { int i; int InterruptOffset; int retval = 0; struct f01_instance_data *instanceData = NULL; struct rmi_F01_control *controlRegisters = NULL; struct rmi_F01_data *dataRegisters = NULL; struct rmi_F01_query *query_registers = NULL; unsigned char query_buffer[21]; pr_debug("%s: RMI4 function $01 detect\n", __func__); /* 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; /* Set up context data. */ instanceData = kzalloc(sizeof(*instanceData), GFP_KERNEL); if (!instanceData) { printk(KERN_ERR "%s: Error allocating memory for F01 context data.\n", __func__); retval = -ENOMEM; goto error_exit; } query_registers = kzalloc(sizeof(*query_registers), GFP_KERNEL); if (!query_registers) { printk(KERN_ERR "%s: Error allocating memory for F01 query registers.\n", __func__); retval = -ENOMEM; goto error_exit; } instanceData->query_registers = query_registers; /* Read the query info and unpack it. */ retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.queryBaseAddr, query_buffer, 21); if (retval) { printk(KERN_ERR "%s : Could not read F01 query registers at 0x%02x. Error %d.\n", __func__, rmifninfo->funcDescriptor.queryBaseAddr, retval); /* Presumably if the read fails, the buffer should be all zeros, so we're OK to continue. */ } query_registers->mfgid = query_buffer[0]; query_registers->properties = query_buffer[1]; query_registers->prod_info[0] = query_buffer[2] & 0x7F; query_registers->prod_info[1] = query_buffer[3] & 0x7F; query_registers->date_code[0] = query_buffer[4] & 0x1F; query_registers->date_code[1] = query_buffer[5] & 0x0F; query_registers->date_code[2] = query_buffer[6] & 0x1F; query_registers->tester_id = (((unsigned short) query_buffer[7] & 0x7F) << 7) | (query_buffer[8] & 0x7F); query_registers->serial_num = (((unsigned short) query_buffer[9] & 0x7F) << 7) | (query_buffer[10] & 0x7F); memcpy(query_registers->prod_id, &query_buffer[11], 10); printk(KERN_DEBUG "%s: RMI4 Protocol Function $01 Query information\n", __func__); printk(KERN_DEBUG "%s: Manufacturer ID: %d %s\n", __func__, query_registers->mfgid, query_registers->mfgid == 1 ? "(Synaptics)" : ""); printk(KERN_DEBUG "%s: Product Properties: 0x%x\n", __func__, query_registers->properties); printk(KERN_DEBUG "%s: Product Info: 0x%x 0x%x\n", __func__, query_registers->prod_info[0], query_registers->prod_info[1]); printk(KERN_DEBUG "%s: Date Code: Year : %d Month: %d Day: %d\n", __func__, query_registers->date_code[0], query_registers->date_code[1], query_registers->date_code[2]); printk(KERN_DEBUG "%s: Tester ID: %d\n", __func__, query_registers->tester_id); printk(KERN_DEBUG "%s: Serial Number: 0x%x\n", __func__, query_registers->serial_num); printk(KERN_DEBUG "%s: Product ID: %s\n", __func__, query_registers->prod_id); /* TODO: size of control registers needs to be computed dynamically. See comment * in rmi.h. */ controlRegisters = kzalloc(sizeof(*controlRegisters), GFP_KERNEL); if (!controlRegisters) { printk(KERN_ERR "%s: Error allocating memory for F01 control registers.\n", __func__); retval = -ENOMEM; goto error_exit; } instanceData->controlRegisters = controlRegisters; retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.controlBaseAddr, (char *)instanceData->controlRegisters, sizeof(struct rmi_F01_control)); if (retval) { printk(KERN_ERR "%s : Could not read F01 control registers at 0x%02x. Error %d.\n", __func__, rmifninfo->funcDescriptor.controlBaseAddr, retval); } /* TODO: size of data registers needs to be computed dynamically. See comment * in rmi.h. */ dataRegisters = kzalloc(sizeof(*dataRegisters), GFP_KERNEL); if (!dataRegisters) { printk(KERN_ERR "%s: Error allocating memory for F01 data registers.\n", __func__); retval = -ENOMEM; goto error_exit; } instanceData->dataRegisters = dataRegisters; rmifninfo->fndata = instanceData; /* Need to get interrupt info to be used later when handling * interrupts. */ rmifninfo->interruptRegister = interruptCount / 8; /* loop through interrupts for each source and or in a bit * to the interrupt mask for each. */ InterruptOffset = interruptCount % 8; for (i = InterruptOffset; i < ((fndescr->interruptSrcCnt & 0x7) + InterruptOffset); i++) { rmifninfo->interruptMask |= 1 << i; } return retval; error_exit: kfree(instanceData); kfree(query_registers); kfree(controlRegisters); kfree(dataRegisters); return retval; }
int FN_34_init(struct rmi_function_device *function_device) { int retval = 0; unsigned char uData[2]; struct rmi_function_info *rmifninfo = function_device->rfi; struct rmi_fn_34_data *fn34data; pr_debug("%s: RMI4 function $34 init\n", __func__); /* */ fn34data = kzalloc(sizeof(struct rmi_fn_34_data), GFP_KERNEL); if (!fn34data) { printk(KERN_ERR "%s: Error allocating memeory for rmi_fn_34_data.\n", __func__); return -ENOMEM; } rmifninfo->fndata = (void *)fn34data; /* */ if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_bootloaderid.attr) < 0) { printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 bootloaderid.\n", __func__); return -ENODEV; } /* */ if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_blocksize.attr) < 0) { printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 blocksize.\n", __func__); return -ENODEV; } /* */ retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.queryBaseAddr, uData, 2); if (retval) { printk(KERN_ERR "%s : Could not read bootloaderid from 0x%x\n", __func__, function_device->function->functionQueryBaseAddr); return retval; } /* */ fn34data->bootloaderid = (unsigned int)uData[0] + (unsigned int)uData[1]*0x100; retval = rmi_read_multiple(rmifninfo->sensor, rmifninfo->funcDescriptor.queryBaseAddr+3, uData, 2); if (retval) { printk(KERN_ERR "%s : Could not read block size from 0x%x\n", __func__, rmifninfo->funcDescriptor.queryBaseAddr+3); return retval; } /* */ fn34data->blocksize = (unsigned int)uData[0] + (unsigned int)uData[1]*0x100; /* */ if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_status.attr) < 0) { printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 status.\n", __func__); return -ENODEV; } /* */ /* */ if (sysfs_create_file(&function_device->dev.kobj, &dev_attr_cmd.attr) < 0) { printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 cmd.\n", __func__); return -ENODEV; } /* */ /* */ if (sysfs_create_bin_file(&function_device->dev.kobj, &dev_attr_data) < 0) { printk(KERN_ERR "%s: Failed to create sysfs file for fn 34 data.\n", __func__); return -ENODEV; } return retval; }