M7350/kernel/drivers/input/touchscreen/synaptics/rmi_bus.c
2024-09-09 08:52:07 +00:00

403 lines
12 KiB
C

/**
* Synaptics Register Mapped Interface (RMI4) - RMI Bus Module.
* Copyright (C) 2007 - 2011, Synaptics Incorporated
*
* Impliments "rmi" bus per Documentation/driver-model/bus.txt
*
* This protocol is layered as follows.
*
*
*
* +-------+ +-------+ +-------+ +--------+
* | Fn32 | | Fn11| | Fn19 | | Fn11 | Devices/Functions
* *---|---+ +--|----+ +----|--+ +----|---* (2D, cap. btns, etc.)
* | | | |
* +----------------+ +----------------+
* | Sensor0 | | Sensor1 | Sensors Dev/Drivers
* +----------------+ +----------------+ (a sensor has one or
* | | more functions)
* | |
* +----------------------------------------+
* | |
* | RMI4 Bus | RMI Bus Layer
* | (this file) |
* *--|-----|------|--------------|---------*
* | | | |
* | | | |
* +-----+-----+-------+--------------------+
* | I2C | SPI | SMBus | etc. | Physical Layer
* +-----+-----+-------+--------------------+
*
*/
/*
* 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 busname[] = "rmi";
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/hrtimer.h>
#include <linux/list.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/input/rmi_platformdata.h>
#include <linux/module.h>
#include "rmi_drvr.h"
#include "rmi.h"
#include "rmi_bus.h"
#include "rmi_sensor.h"
#include "rmi_function.h"
/* list of physical drivers - i2c, spi, etc. */
static LIST_HEAD(phys_drivers);
static DEFINE_MUTEX(phys_drivers_mutex);
/* list of sensors found on a physical bus (i2c, smi, etc.)*/
static LIST_HEAD(sensor_drivers);
static DEFINE_MUTEX(sensor_drivers_mutex);
static LIST_HEAD(sensor_devices);
static DEFINE_MUTEX(sensor_devices_mutex);
#define PDT_START_SCAN_LOCATION 0x00E9
#define PDT_END_SCAN_LOCATION 0x0005
#define PDT_ENTRY_SIZE 0x0006
/* definitions for rmi bus */
struct device rmi_bus_device;
struct bus_type rmi_bus_type;
EXPORT_SYMBOL(rmi_bus_type);
/*
* This method is called, perhaps multiple times, whenever a new device or driver
* is added for this bus. It should return a nonzero value if the given device can be
* handled by the given driver. This function must be handled at the bus level,
* because that is where the proper logic exists; the core kernel cannot know how
* to match devices and drivers for every possible bus type
* The match function does a comparison between the hardware ID provided by
* the device itself and the IDs supported by the driver.
*
*/
static int rmi_bus_match(struct device *dev, struct device_driver *driver)
{
printk(KERN_DEBUG "%s: Matching %s for rmi bus.\n", __func__, dev->bus->name);
return !strncmp(dev->bus->name, driver->name, strlen(driver->name));
}
/** Stub for now.
*/
static int rmi_bus_suspend(struct device *dev, pm_message_t state)
{
printk(KERN_INFO "%s: RMI bus suspending.", __func__);
return 0;
}
/** Stub for now.
*/
static int rmi_bus_resume(struct device *dev)
{
printk(KERN_INFO "%s: RMI bus resuming.", __func__);
return 0;
}
/*
* This method is called, whenever a new device is added for this bus.
* It will scan the devices PDT to get the function $01 query, control,
* command and data regsiters so that it can create a function $01 (sensor)
* device for the new physical device. It also caches the PDT for later use by
* other functions that are created for the device. For example, if a function
* $11 is found it will need the query, control, command and data register
* addresses for that function. The new function could re-scan the PDT but
* since it is being done here we can cache it and keep it around.
*
* TODO: If the device is reset or some action takes place that would invalidate
* the PDT - such as a reflash of the firmware - then the device should be re-added
* to the bus and the PDT re-scanned and cached.
*
*/
int rmi_register_sensor(struct rmi_phys_driver *rpd, struct rmi_sensordata *sensordata)
{
int i;
int pdt_entry_count = 0;
struct rmi_sensor_device *rmi_sensor_dev;
struct rmi_function_info *rfi;
struct rmi_function_descriptor rmi_fd;
int retval;
static int index;
/* Make sure we have a read, write, read_multiple, write_multiple
function pointers from whatever physical layer the sensor is on.
*/
if (!rpd->name) {
printk(KERN_ERR "%s: Physical driver must specify a name",
__func__);
return -EINVAL;
}
if (!rpd->write) {
printk(KERN_ERR
"%s: Physical driver %s must specify a writer.",
__func__, rpd->name);
return -EINVAL;
}
if (!rpd->read) {
printk(KERN_ERR
"%s: Physical driver %s must specify a reader.",
__func__, rpd->name);
return -EINVAL;
}
if (!rpd->write_multiple) {
printk(KERN_ERR "%s: Physical driver %s must specify a "
"multiple writer.",
__func__, rpd->name);
return -EINVAL;
}
if (!rpd->read_multiple) {
printk(KERN_ERR "%s: Physical driver %s must specify a "
"multiple reader.",
__func__, rpd->name);
return -EINVAL;
}
/* Get some information from the device */
printk(KERN_DEBUG "%s: Identifying sensors by presence of F01...", __func__);
rmi_sensor_dev = NULL;
/* Scan the page descriptor table until we find F01. If we find that,
* we assume that we can reliably talk to this sensor.
*/
for (i = PDT_START_SCAN_LOCATION; /* Register the rmi sensor driver */
i >= PDT_END_SCAN_LOCATION;
i -= PDT_ENTRY_SIZE) {
retval = rpd->read_multiple(rpd, i, (char *)&rmi_fd,
sizeof(rmi_fd));
if (!retval) {
rfi = NULL;
if (rmi_fd.functionNum != 0x00 && rmi_fd.functionNum != 0xff) {
pdt_entry_count++;
if ((rmi_fd.functionNum & 0xff) == 0x01) {
printk(KERN_DEBUG "%s: F01 Found - RMI Device Control", __func__);
/* This appears to be a valid device, so create a sensor
* device and sensor driver for it. */
rmi_sensor_dev = kzalloc(sizeof(*rmi_sensor_dev), GFP_KERNEL);
if (!rmi_sensor_dev) {
printk(KERN_ERR "%s: Error allocating memory for rmi_sensor_device\n", __func__);
retval = -ENOMEM;
goto exit_fail;
}
rmi_sensor_dev->dev.bus = &rmi_bus_type;
retval = rmi_sensor_register_device(rmi_sensor_dev, index++);
if (retval < 0) {
printk(KERN_ERR "%s: Error %d registering sensor device.", __func__, retval);
goto exit_fail;
}
rmi_sensor_dev->driver = kzalloc(sizeof(struct rmi_sensor_driver), GFP_KERNEL);
if (!rmi_sensor_dev->driver) {
printk(KERN_ERR "%s: Error allocating memory for rmi_sensor_driver\n", __func__);
retval = -ENOMEM;
goto exit_fail;
}
rmi_sensor_dev->driver->sensor_device = rmi_sensor_dev;
rmi_sensor_dev->driver->polling_required = rpd->polling_required;
rmi_sensor_dev->driver->rpd = rpd;
if (sensordata)
rmi_sensor_dev->driver->perfunctiondata = sensordata->perfunctiondata;
INIT_LIST_HEAD(&rmi_sensor_dev->driver->functions);
retval = rmi_sensor_register_driver(rmi_sensor_dev->driver);
if (retval < 0) {
printk(KERN_ERR "%s: Error %d registering sensor driver.", __func__, retval);
goto exit_fail;
}
/* link the attention fn in the rpd to the sensor attn fn */
rpd->sensor = rmi_sensor_dev->driver;
rpd->attention = rmi_sensor_dev->driver->attention;
/* Add it into the list of sensors on the rmi bus */
mutex_lock(&sensor_devices_mutex);
list_add_tail(&rmi_sensor_dev->sensors, &sensor_devices);
mutex_unlock(&sensor_devices_mutex);
/* All done with this sensor, fall out of PDT scan loop. */
break;
} else {
/* Just print out the function found for now */
printk(KERN_DEBUG "%s: Found Function %02x - Ignored.\n", __func__, rmi_fd.functionNum & 0xff);
}
} else {
/* A zero or 0xff in the function number
signals the end of the PDT */
pr_debug("%s: Found End of PDT.",
__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.",
__func__, retval);
break;
}
}
/* If we actually found a sensor, keep it around. */
if (rmi_sensor_dev) {
/* Add physical driver struct to list */
mutex_lock(&phys_drivers_mutex);
list_add_tail(&rpd->drivers, &phys_drivers);
mutex_unlock(&phys_drivers_mutex);
printk(KERN_DEBUG "%s: Registered sensor drivers.", __func__);
retval = 0;
} else {
printk(KERN_ERR "%s: Failed to find sensor. PDT contained %d entries.", __func__, pdt_entry_count);
retval = -ENODEV;
}
exit_fail:
return retval;
}
EXPORT_SYMBOL(rmi_register_sensor);
int rmi_unregister_sensors(struct rmi_phys_driver *rpd)
{
if (rpd->sensor) {
printk(KERN_WARNING "%s: WARNING: unregister of %s while %s still attached.",
__func__, rpd->name, rpd->sensor->drv.name);
}
pr_debug("%s: Unregistering sensor drivers %s\n", __func__, rpd->name);
/* TODO: We should call sensor_teardown() for each sensor before we get
* rid of this list.
*/
mutex_lock(&sensor_drivers_mutex);
list_del(&rpd->sensor->sensor_drivers);
mutex_unlock(&sensor_drivers_mutex);
return 0;
}
EXPORT_SYMBOL(rmi_unregister_sensors);
static void rmi_bus_dev_release(struct device *dev)
{
printk(KERN_DEBUG "rmi bus device release\n");
}
int rmi_register_bus_device(struct device *rmibusdev)
{
printk(KERN_DEBUG "%s: Registering RMI4 bus device.\n", __func__);
/* Here, we simply fill in some of the embedded device structure fields
(which individual drivers should not need to know about), and register
the device with the driver core. */
rmibusdev->bus = &rmi_bus_type;
rmibusdev->parent = &rmi_bus_device;
rmibusdev->release = rmi_bus_dev_release;
dev_set_name(rmibusdev, "rmi");
/* If we wanted to add bus-specific attributes to the device, we could do so here.*/
return device_register(rmibusdev);
}
EXPORT_SYMBOL(rmi_register_bus_device);
void rmi_unregister_bus_device(struct device *rmibusdev)
{
printk(KERN_DEBUG "%s: Unregistering bus device.", __func__);
device_unregister(rmibusdev);
}
EXPORT_SYMBOL(rmi_unregister_bus_device);
static int __init rmi_bus_init(void)
{
int status;
status = 0;
printk(KERN_INFO "%s: RMI Bus Driver Init", __func__);
/* Register the rmi bus */
rmi_bus_type.name = busname;
rmi_bus_type.match = rmi_bus_match;
rmi_bus_type.suspend = rmi_bus_suspend;
rmi_bus_type.resume = rmi_bus_resume;
status = bus_register(&rmi_bus_type);
if (status < 0) {
printk(KERN_ERR "%s: Error %d registering the rmi bus.", __func__, status);
goto err_exit;
}
printk(KERN_DEBUG "%s: registered bus.", __func__);
#if 0
/** This doesn't seem to be required any more. It worked OK in Froyo,
* but breaks in Gingerbread */
/* Register the rmi bus device - "rmi". There is only one rmi bus device. */
status = rmi_register_bus_device(&rmi_bus_device);
if (status < 0) {
printk(KERN_ERR "%s: Error %d registering rmi bus device.", __func__, status);
bus_unregister(&rmi_bus_type);
goto err_exit;
}
printk(KERN_DEBUG "%s: Registered bus device.", __func__);
#endif
return 0;
err_exit:
return status;
}
static void __exit rmi_bus_exit(void)
{
printk(KERN_DEBUG "%s: RMI Bus Driver Exit.", __func__);
/* Unregister the rmi bus device - "rmi". There is only one rmi bus device. */
rmi_unregister_bus_device(&rmi_bus_device);
/* Unregister the rmi bus */
bus_unregister(&rmi_bus_type);
}
module_init(rmi_bus_init);
module_exit(rmi_bus_exit);
MODULE_AUTHOR("Synaptics, Inc.");
MODULE_DESCRIPTION("RMI4 Driver");
MODULE_LICENSE("GPL");