Esempio n. 1
0
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]);
	}

}
Esempio n. 4
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}