/** * Synaptics Register Mapped Interface (RMI4) - RMI Sensor Module. * 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. * *############################################################################ */ static const char sensorname[] = "sensor"; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "rmi_drvr.h" #include "rmi_bus.h" #include "rmi_function.h" #include "rmi_sensor.h" long polltime = 25000000; /* Shared with rmi_function.c. */ EXPORT_SYMBOL(polltime); module_param(polltime, long, 0644); MODULE_PARM_DESC(polltime, "How long to wait between polls (in nano seconds)."); #define PDT_START_SCAN_LOCATION 0x00E9 #define PDT_END_SCAN_LOCATION 0x0005 #define PDT_ENTRY_SIZE 0x0006 static DEFINE_MUTEX(rfi_mutex); struct rmi_functions *rmi_find_function(int functionNum); int rmi_read(struct rmi_sensor_driver *sensor, unsigned short address, char *dest) { struct rmi_phys_driver *rpd = sensor->rpd; if (!rpd) return -ENODEV; return rpd->read(rpd, address, dest); } EXPORT_SYMBOL(rmi_read); int rmi_write(struct rmi_sensor_driver *sensor, unsigned short address, unsigned char data) { struct rmi_phys_driver *rpd = sensor->rpd; if (!rpd) return -ENODEV; return rpd->write(rpd, address, data); } EXPORT_SYMBOL(rmi_write); int rmi_read_multiple(struct rmi_sensor_driver *sensor, unsigned short address, char *dest, int length) { struct rmi_phys_driver *rpd = sensor->rpd; if (!rpd) return -ENODEV; return rpd->read_multiple(rpd, address, dest, length); } EXPORT_SYMBOL(rmi_read_multiple); int rmi_write_multiple(struct rmi_sensor_driver *sensor, unsigned short address, unsigned char *data, int length) { struct rmi_phys_driver *rpd = sensor->rpd; if (!rpd) return -ENODEV; return rpd->write_multiple(rpd, address, data, length); } EXPORT_SYMBOL(rmi_write_multiple); /* Utility routine to set bits in a register. */ int rmi_set_bits(struct rmi_sensor_driver *sensor, unsigned short address, unsigned char bits) { unsigned char reg_contents; int retval; retval = rmi_read(sensor, address, ®_contents); if (retval) return retval; reg_contents = reg_contents | bits; retval = rmi_write(sensor, address, reg_contents); if (retval == 1) return 0; else if (retval == 0) return -EINVAL; /* TODO: What should this be? */ else return retval; } EXPORT_SYMBOL(rmi_set_bits); /* Utility routine to clear bits in a register. */ int rmi_clear_bits(struct rmi_sensor_driver *sensor, unsigned short address, unsigned char bits) { unsigned char reg_contents; int retval; retval = rmi_read(sensor, address, ®_contents); if (retval) return retval; reg_contents = reg_contents & ~bits; retval = rmi_write(sensor, address, reg_contents); if (retval == 1) return 0; else if (retval == 0) return -EINVAL; /* TODO: What should this be? */ else return retval; } EXPORT_SYMBOL(rmi_clear_bits); /* Utility routine to set the value of a bit field in a register. */ int rmi_set_bit_field(struct rmi_sensor_driver *sensor, unsigned short address, unsigned char field_mask, unsigned char bits) { unsigned char reg_contents; int retval; retval = rmi_read(sensor, address, ®_contents); if (retval) return retval; reg_contents = (reg_contents & ~field_mask) | bits; retval = rmi_write(sensor, address, reg_contents); if (retval == 1) return 0; else if (retval == 0) return -EINVAL; /* TODO: What should this be? */ else return retval; } EXPORT_SYMBOL(rmi_set_bit_field); bool rmi_polling_required(struct rmi_sensor_driver *sensor) { return sensor->polling_required; } EXPORT_SYMBOL(rmi_polling_required); /** Functions can call this in order to dispatch IRQs. */ void dispatchIRQs(struct rmi_sensor_driver *sensor, unsigned int irqStatus) { struct rmi_function_info *functionInfo; list_for_each_entry(functionInfo, &sensor->functions, link) { if ((functionInfo->interruptMask & irqStatus)) { if (functionInfo->function_device-> rmi_funcs->inthandler) { /* Call the functions interrupt handler function. */ functionInfo->function_device->rmi_funcs-> inthandler(functionInfo, (functionInfo->interruptMask & irqStatus)); } } } } /** * This is the function we pass to the RMI4 subsystem so we can be notified * when attention is required. It may be called in interrupt context. */ static void attention(struct rmi_phys_driver *physdrvr, int instance) { /* All we have to do is schedule work. */ /* TODO: It's possible that workIsReady is not really needed anymore. * Investigate this to see if the race condition between setting up * the work and enabling the interrupt still exists. */ if (physdrvr->sensor->workIsReady) { schedule_work(&(physdrvr->sensor->work)); } else { /* Got an interrupt but we're not ready so enable the irq * so it doesn't get hung up */ printk(KERN_DEBUG "%s: Work not initialized yet -" "enabling irqs.\n", __func__); enable_irq(physdrvr->irq); } } /** * This notifies any interested functions that there * is an Attention interrupt. The interested functions should take * appropriate * actions (such as reading the interrupt status register and dispatching any * appropriate RMI4 interrupts). */ void attn_notify(struct rmi_sensor_driver *sensor) { struct rmi_function_info *functionInfo; /* check each function that has data sources and if the interrupt for * that triggered then call that RMI4 functions report() function to * gather data and report it to the input subsystem */ list_for_each_entry(functionInfo, &sensor->functions, link) { if (functionInfo->function_device && functionInfo->function_device->rmi_funcs->attention) functionInfo->function_device-> rmi_funcs->attention(functionInfo); } } /* This is the worker function - for now it simply has to call attn_notify. * This work should be scheduled whenever an ATTN interrupt is asserted by * the touch sensor. * We then call attn_notify to dispatch notification of the ATTN interrupt * to all * interested functions. After all the attention handling functions * have returned, it is presumed safe to re-enable the Attention interrupt. */ static void sensor_work_func(struct work_struct *work) { struct rmi_sensor_driver *sensor = container_of(work, struct rmi_sensor_driver, work); attn_notify(sensor); /* we only need to enable the irq if doing interrupts */ if (!rmi_polling_required(sensor)) enable_irq(sensor->rpd->irq); } /* This is the timer function for polling - it simply has to schedule work * and restart the timer. */ static enum hrtimer_restart sensor_poll_timer_func(struct hrtimer *timer) { struct rmi_sensor_driver *sensor = container_of(timer, struct rmi_sensor_driver, timer); schedule_work(&sensor->work); hrtimer_start(&sensor->timer, ktime_set(0, polltime), HRTIMER_MODE_REL); return HRTIMER_NORESTART; } /* This is the probe function passed to the RMI4 subsystem that gives us a * chance to recognize an RMI4 device. In this case, we're looking for * Synaptics devices that have data sources - such as touch screens, buttons, * etc. * * TODO: Well, it used to do this. I'm not sure it's required any more. */ static int probe(struct rmi_sensor_driver *sensor) { struct rmi_phys_driver *rpd; rpd = sensor->rpd; if (!rpd) { printk(KERN_ERR "%s: Invalid rmi physical driver - null ptr:" "%p\n", __func__, rpd); return 0; } return 1; } static void config(struct rmi_sensor_driver *sensor) { /* For each data source we had detected print info and set up interrupts or polling. */ struct rmi_function_info *functionInfo; struct rmi_phys_driver *rpd; rpd = sensor->rpd; /* get ptr to rmi_physical_driver from app */ list_for_each_entry(functionInfo, &sensor->functions, link) { /* Get and print some info about the data sources... */ struct rmi_functions *fn; bool found = false; /* check if function number matches - if so call that config function */ fn = rmi_find_function(functionInfo->functionNum); if (fn) { found = true; if (fn->config) { fn->config(functionInfo); } else { /* the developer did not add in the pointer to the config function into rmi4_supported_data_src_functions */ printk(KERN_ERR "%s: no config function for " "function 0x%x\n", __func__, functionInfo->functionNum); break; } } if (!found) { /* if no support found for this RMI4 function it means the developer did not add the appropriate function pointer list into the rmi4_supported_data_src_functions array and/or did not bump up the number of supported RMI4 functions in rmi.h as required */ printk(KERN_ERR "%s: could not find support " "for function 0x%x\n", __func__, functionInfo->functionNum); } } /* This will handle interrupts on the ATTN line (interrupt driven) * or will be called every poll interval (when we're not interrupt * driven). */ INIT_WORK(&sensor->work, sensor_work_func); sensor->workIsReady = true; if (rmi_polling_required(sensor)) { /* We're polling driven, so set up the polling timer and timer function. */ hrtimer_init(&sensor->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sensor->timer.function = sensor_poll_timer_func; hrtimer_start(&sensor->timer, ktime_set(1, 0), HRTIMER_MODE_REL); } } /** Just a stub for now. */ static int rmi_sensor_suspend(struct device *dev, pm_message_t state) { printk(KERN_INFO "%s: sensor suspend called.", __func__); return 0; } /** Just a stub for now. */ static int rmi_sensor_resume(struct device *dev) { printk(KERN_INFO "%s: sensor resume called.", __func__); return 0; } /* * This method is called, whenever a new sensor device is added for the rmi * bus. * * It will scan the devices PDT to determine the supported functions * and create a new function device for each of these. It will read * the query, control, command and data regsiters for the function * to be used for each newly created function device. * * The sensor device is then bound to every function it supports. * */ int rmi_sensor_register_functions(struct rmi_sensor_driver *sensor) { struct rmi_function_device *function; unsigned int interruptRegisterCount; struct rmi_phys_driver *rpd; int i; unsigned char interruptCount; struct rmi_function_info *functionInfo; struct rmi_function_descriptor rmi_fd; struct rmi_functions *fn; int retval; pr_debug("%s: Registering sensor functions\n", __func__); retval = 0; /* Scan device for functions that may be supported */ { pr_debug("%s: Scanning sensor for Functions:\n", __func__); interruptCount = 0; rpd = sensor->rpd; /* Read the Page Descriptor Table to determine what functions * are present */ printk(KERN_DEBUG "%s: Scanning page descriptors.", __func__); for (i = PDT_START_SCAN_LOCATION; i >= PDT_END_SCAN_LOCATION; i -= PDT_ENTRY_SIZE) { printk(KERN_DEBUG "%s: Reading page descriptor 0x%02x", __func__, i); retval = rpd->read_multiple(rpd, i, (char *)&rmi_fd, sizeof(rmi_fd)); if (!retval) { functionInfo = NULL; if (rmi_fd.functionNum != 0x00 && rmi_fd.functionNum != 0xff) { printk(KERN_DEBUG "%s: F%02x - queries %02x commands %02x control %02x data %02x ints %02x", __func__, rmi_fd.functionNum, rmi_fd.queryBaseAddr, rmi_fd.commandBaseAddr, rmi_fd.controlBaseAddr, rmi_fd.dataBaseAddr, rmi_fd.interruptSrcCnt); if ((rmi_fd.functionNum & 0xff) == 0x01) printk(KERN_DEBUG "%s: Fn $01 Found - RMI Device Control", __func__); /* determine if the function is supported and if so * then bind this function device to the sensor */ if (rmi_fd.interruptSrcCnt) { functionInfo = kzalloc(sizeof(*functionInfo), GFP_KERNEL); if (!functionInfo) { printk(KERN_ERR "%s: could not allocate memory for function 0x%x.", __func__, rmi_fd.functionNum); retval = -ENOMEM; goto exit_fail; } functionInfo->sensor = sensor; functionInfo->functionNum = (rmi_fd.functionNum & 0xff); INIT_LIST_HEAD(&functionInfo->link); /* Get the ptr to the detect function based on * the function number */ printk(KERN_DEBUG "%s: Checking for RMI function F%02x.", __func__, rmi_fd.functionNum); fn = rmi_find_function(rmi_fd.functionNum); if (fn) { retval = fn->detect(functionInfo, &rmi_fd, interruptCount); if (retval) printk(KERN_ERR "%s: Function detect for F%02x failed with %d.", __func__, rmi_fd.functionNum, retval); /* Create a function device and function driver for this Fn */ function = kzalloc(sizeof(*function), GFP_KERNEL); if (!function) { printk(KERN_ERR "%s: Error allocating memory for rmi_function_device.", __func__); return -ENOMEM; } function->dev.parent = &sensor->sensor_device->dev; function->dev.bus = sensor->sensor_device->dev.bus; function->rmi_funcs = fn; function->sensor = sensor; function->rfi = functionInfo; functionInfo->function_device = function; /* Check if we have an interrupt mask of 0 and a non-NULL interrupt handler function and print a debug message since we should never have this. */ if (functionInfo->interruptMask == 0 && fn->inthandler != NULL) { printk(KERN_DEBUG "%s: Can't have a zero interrupt mask for function F%02x (which requires an interrupt handler).\n", __func__, rmi_fd.functionNum); } /* Check if we have a non-zero interrupt mask and a NULL interrupt handler function and print a debug message since we should never have this. */ if (functionInfo->interruptMask != 0 && fn->inthandler == NULL) { printk(KERN_DEBUG "%s: Can't have a non-zero interrupt mask %d for function F%02x with a NULL inthandler fn.\n", __func__, functionInfo->interruptMask, rmi_fd.functionNum); } /* Register the rmi function device */ retval = rmi_function_register_device(function, rmi_fd.functionNum); if (retval) { printk(KERN_ERR "%s: Failed rmi_function_register_device.\n", __func__); return retval; } } else { printk(KERN_ERR "%s: could not find support for function 0x%02X.\n", __func__, rmi_fd.functionNum); } } else { printk(KERN_DEBUG "%s: Found function F%02x - Ignored.\n", __func__, rmi_fd.functionNum & 0xff); } /* bump interrupt count for next iteration */ /* NOTE: The value 7 is reserved - for now, only bump up one for an interrupt count of 7 */ if ((rmi_fd.interruptSrcCnt & 0x7) == 0x7) { interruptCount += 1; } else { interruptCount += (rmi_fd.interruptSrcCnt & 0x7); } /* link this function info to the RMI module infos list of functions */ if (functionInfo == NULL) { printk(KERN_DEBUG "%s: WTF? functionInfo is null here.", __func__); } else { printk(KERN_DEBUG "%s: Adding function F%02x with %d sources.\n", __func__, functionInfo->functionNum, functionInfo->numSources); mutex_lock(&rfi_mutex); list_add_tail(&functionInfo->link, &sensor->functions); mutex_unlock(&rfi_mutex); } } else { /* A zero or 0xff in the function number signals the end of the PDT */ printk(KERN_DEBUG "%s: Found End of PDT\n", __func__); break; } } else { /* failed to read next PDT entry - end PDT scan - this may result in an incomplete set of recognized functions - should probably return an error but the driver may still be viable for diagnostics and debugging so let's let it continue. */ printk(KERN_ERR "%s: Read Error %d when reading next PDT entry - " "ending PDT scan.\n", __func__, retval); break; } } printk(KERN_DEBUG "%s: Done scanning.", __func__); /* calculate the interrupt register count - used in the ISR to read the correct number of interrupt registers */ interruptRegisterCount = (interruptCount + 7) / 8; sensor->interruptRegisterCount = interruptRegisterCount; /* TODO: Is this needed by the sensor anymore? */ } return 0; exit_fail: return retval; } EXPORT_SYMBOL(rmi_sensor_register_functions); int rmi_sensor_register_device(struct rmi_sensor_device *dev, int index) { int status; printk(KERN_INFO "%s: Registering sensor device.\n", __func__); /* make name - sensor00, sensor01, etc. */ dev_set_name(&dev->dev, "sensor%02d", index); status = device_register(&dev->dev); return status; } EXPORT_SYMBOL(rmi_sensor_register_device); static void rmi_sensor_unregister_device(struct rmi_sensor_device *rmisensordev) { printk(KERN_INFO "%s: Unregistering sensor device.\n", __func__); device_unregister(&rmisensordev->dev); } EXPORT_SYMBOL(rmi_sensor_unregister_device); int rmi_sensor_register_driver(struct rmi_sensor_driver *driver) { static int index; int ret; char *drvrname; driver->workIsReady = false; printk(KERN_INFO "%s: Registering sensor driver.\n", __func__); driver->dispatchIRQs = dispatchIRQs; driver->attention = attention; driver->config = config; driver->probe = probe; /* assign the bus type for this driver to be rmi bus */ driver->drv.bus = &rmi_bus_type; driver->drv.suspend = rmi_sensor_suspend; driver->drv.resume = rmi_sensor_resume; /* Create a function device and function driver for this Fn */ drvrname = kzalloc(sizeof(sensorname) + 4, GFP_KERNEL); if (!drvrname) { printk(KERN_ERR "%s: Error allocating memeory for rmi_sensor_driver name.\n", __func__); return -ENOMEM; } sprintf(drvrname, "sensor%02d", index++); driver->drv.name = drvrname; driver->module = driver->drv.owner; /* register the sensor driver */ ret = driver_register(&driver->drv); if (ret) { printk(KERN_ERR "%s: Failed driver_register %d\n", __func__, ret); goto exit_fail; } /* register the functions on the sensor */ ret = rmi_sensor_register_functions(driver); if (ret) { printk(KERN_ERR "%s: Failed rmi_sensor_register_functions %d\n", __func__, ret); } /* configure the sensor - enable interrupts for each function, init work, set polling timer or adjust report rate, etc. */ config(driver); printk(KERN_DEBUG "%s: sensor driver registration completed.", __func__); exit_fail: return ret; } EXPORT_SYMBOL(rmi_sensor_register_driver); static void rmi_sensor_unregister_driver(struct rmi_sensor_driver *driver) { printk(KERN_DEBUG "%s: Unregistering sensor driver.\n", __func__); /* Stop the polling timer if doing polling */ if (rmi_polling_required(driver)) hrtimer_cancel(&driver->timer); flush_scheduled_work(); /* Make sure all scheduled work is stopped */ driver_unregister(&driver->drv); } EXPORT_SYMBOL(rmi_sensor_unregister_driver); static int __init rmi_sensor_init(void) { printk(KERN_DEBUG "%s: RMI Sensor Init\n", __func__); return 0; } static void __exit rmi_sensor_exit(void) { printk(KERN_DEBUG "%s: RMI Sensor Driver Exit\n", __func__); flush_scheduled_work(); /* Make sure all scheduled work is stopped */ } module_init(rmi_sensor_init); module_exit(rmi_sensor_exit); MODULE_AUTHOR("Synaptics, Inc."); MODULE_DESCRIPTION("RMI4 Sensor Driver"); MODULE_LICENSE("GPL");