123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663 |
- /**
- * 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 <linux/kernel.h>
- #include <linux/gpio.h>
- #include <linux/list.h>
- #include <linux/device.h>
- #include <linux/hrtimer.h>
- #include <linux/miscdevice.h>
- #include <linux/fs.h>
- #include <linux/delay.h>
- #include <linux/uaccess.h>
- #include <linux/slab.h>
- #include <linux/kthread.h>
- #include <linux/freezer.h>
- #include <linux/input.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
- #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");
|