610 lines
18 KiB
C
Executable File
610 lines
18 KiB
C
Executable File
/*
|
|
* Copyright (c) 2011 Synaptics Incorporated
|
|
* Copyright (c) 2011 Unixphere
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
#ifndef _RMI_H
|
|
#define _RMI_H
|
|
#include <linux/kernel.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/module.h>
|
|
#include <linux/types.h>
|
|
#include <linux/device.h>
|
|
#include <linux/cdev.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/stat.h>
|
|
#include <linux/wait.h>
|
|
#include <linux/list.h>
|
|
#include <linux/interrupt.h>
|
|
|
|
#ifdef CONFIG_RMI_DEBUG
|
|
#include <linux/debugfs.h>
|
|
#endif
|
|
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
#include <linux/earlysuspend.h>
|
|
#endif
|
|
|
|
|
|
/* Permissions for sysfs attributes. Since the permissions policy will change
|
|
* on a global basis in the future, rather than edit all sysfs attrs everywhere
|
|
* in the driver (and risk screwing that up in the process), we use this handy
|
|
* set of #defines. That way when we change the policy for sysfs permissions,
|
|
* we only need to change them here.
|
|
*/
|
|
#define RMI_RO_ATTR S_IRUGO
|
|
#define RMI_RW_ATTR (S_IRUGO | S_IWUGO)
|
|
#define RMI_WO_ATTR S_IWUGO
|
|
|
|
#define PDT_START_SCAN_LOCATION 0x00e9
|
|
|
|
enum rmi_attn_polarity {
|
|
RMI_ATTN_ACTIVE_LOW = 0,
|
|
RMI_ATTN_ACTIVE_HIGH = 1
|
|
};
|
|
|
|
/**
|
|
* struct rmi_f11_axis_alignment - target axis alignment
|
|
* @swap_axes: set to TRUE if desired to swap x- and y-axis
|
|
* @flip_x: set to TRUE if desired to flip direction on x-axis
|
|
* @flip_y: set to TRUE if desired to flip direction on y-axis
|
|
*/
|
|
struct rmi_f11_2d_axis_alignment {
|
|
bool swap_axes;
|
|
bool flip_x;
|
|
bool flip_y;
|
|
int clip_X_low;
|
|
int clip_Y_low;
|
|
int clip_X_high;
|
|
int clip_Y_high;
|
|
int offset_X;
|
|
int offset_Y;
|
|
int rel_report_enabled;
|
|
};
|
|
|
|
/**
|
|
* struct rmi_f01_power - override default power management settings.
|
|
*
|
|
*/
|
|
enum rmi_f01_nosleep {
|
|
RMI_F01_NOSLEEP_DEFAULT = 0,
|
|
RMI_F01_NOSLEEP_OFF = 1,
|
|
RMI_F01_NOSLEEP_ON = 2
|
|
};
|
|
|
|
struct rmi_f01_power_management {
|
|
enum rmi_f01_nosleep nosleep;
|
|
u8 wakeup_threshold;
|
|
u8 doze_holdoff;
|
|
u8 doze_interval;
|
|
};
|
|
|
|
struct rmi_f19_button_map {
|
|
unsigned char nbuttons;
|
|
unsigned char *map;
|
|
};
|
|
|
|
struct rmi_f1a_button_map {
|
|
unsigned char nbuttons;
|
|
unsigned char *map;
|
|
};
|
|
|
|
struct virtualbutton_map {
|
|
u16 x;
|
|
u16 y;
|
|
u16 width;
|
|
u16 height;
|
|
u16 code;
|
|
};
|
|
|
|
struct rmi_f11_virtualbutton_map {
|
|
u8 buttons;
|
|
struct virtualbutton_map *map;
|
|
};
|
|
struct rmi_device_platform_data_spi {
|
|
int block_delay_us;
|
|
int split_read_block_delay_us;
|
|
int read_delay_us;
|
|
int write_delay_us;
|
|
int split_read_byte_delay_us;
|
|
int pre_delay_us;
|
|
int post_delay_us;
|
|
|
|
void *cs_assert_data;
|
|
int (*cs_assert) (const void *cs_assert_data, const bool assert);
|
|
};
|
|
|
|
struct rmi_device_platform_data {
|
|
char *driver_name;
|
|
char *sensor_name; /* Used for diagnostics. */
|
|
|
|
int attn_gpio;
|
|
enum rmi_attn_polarity attn_polarity;
|
|
bool level_triggered;
|
|
void *gpio_data;
|
|
int (*gpio_config)(void *gpio_data, bool configure);
|
|
|
|
int reset_delay_ms;
|
|
|
|
struct rmi_device_platform_data_spi spi_data;
|
|
|
|
/* function handler pdata */
|
|
struct rmi_f01_power_management power_management;
|
|
struct rmi_f11_2d_axis_alignment axis_align;
|
|
struct rmi_f19_button_map *button_map;
|
|
struct rmi_f1a_button_map *f1a_button_map;
|
|
struct rmi_f11_virtualbutton_map *virtualbutton_map;
|
|
int (*init_hw)(void);
|
|
#ifdef CONFIG_PM
|
|
void *pm_data;
|
|
int (*pre_suspend) (const void *pm_data);
|
|
int (*post_resume) (const void *pm_data);
|
|
#endif
|
|
};
|
|
|
|
/**
|
|
* struct rmi_function_descriptor - RMI function base addresses
|
|
* @query_base_addr: The RMI Query base address
|
|
* @command_base_addr: The RMI Command base address
|
|
* @control_base_addr: The RMI Control base address
|
|
* @data_base_addr: The RMI Data base address
|
|
* @interrupt_source_count: The number of irqs this RMI function needs
|
|
* @function_number: The RMI function number
|
|
*
|
|
* This struct is used when iterating the Page Description Table. The addresses
|
|
* are 16-bit values to include the current page address.
|
|
*
|
|
*/
|
|
struct rmi_function_descriptor {
|
|
u16 query_base_addr;
|
|
u16 command_base_addr;
|
|
u16 control_base_addr;
|
|
u16 data_base_addr;
|
|
u8 interrupt_source_count;
|
|
u8 function_number;
|
|
u8 function_version;
|
|
};
|
|
|
|
struct rmi_function_container;
|
|
struct rmi_device;
|
|
|
|
/**
|
|
* struct rmi_function_handler - an RMI function handler
|
|
* @func: The RMI function number
|
|
* @init: Callback for RMI function init
|
|
* @attention: Callback for RMI function attention
|
|
* @suspend: Callback for function suspend, returns 0 for success.
|
|
* @resume: Callback for RMI function resume, returns 0 for success.
|
|
* @remove: Callback for RMI function removal
|
|
*
|
|
* This struct describes the interface of an RMI function. These are
|
|
* registered to the bus using the rmi_register_function_driver() call.
|
|
*
|
|
*/
|
|
struct rmi_function_handler {
|
|
int func;
|
|
int (*init)(struct rmi_function_container *fc);
|
|
int (*config)(struct rmi_function_container *fc);
|
|
int (*reset)(struct rmi_function_container *fc);
|
|
int (*attention)(struct rmi_function_container *fc, u8 *irq_bits);
|
|
#ifdef CONFIG_PM
|
|
int (*suspend)(struct rmi_function_container *fc);
|
|
int (*resume)(struct rmi_function_container *fc);
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
int (*early_suspend)(struct rmi_function_container *fc);
|
|
int (*late_resume)(struct rmi_function_container *fc);
|
|
#endif
|
|
#endif
|
|
void (*remove)(struct rmi_function_container *fc);
|
|
};
|
|
|
|
/**
|
|
* struct rmi_function_container - an element in a function handler list
|
|
* @list: The list
|
|
* @fd: The function descriptor of the RMI function
|
|
* @rmi_dev: Pointer to the RMI device associated with this function container
|
|
* @fh: The callbacks connected to this function
|
|
* @num_of_irqs: The number of irqs needed by this function
|
|
* @irq_pos: The position in the irq bitfield this function holds
|
|
* @data: Private data pointer
|
|
*
|
|
*/
|
|
struct rmi_function_container {
|
|
struct list_head list;
|
|
|
|
struct rmi_function_descriptor fd;
|
|
struct rmi_device *rmi_dev;
|
|
struct rmi_function_handler *fh;
|
|
struct device dev;
|
|
|
|
#ifdef CONFIG_RMI4_DEBUG
|
|
struct dentry *debugfs_root;
|
|
#endif
|
|
|
|
int num_of_irqs;
|
|
int irq_pos;
|
|
u8 *irq_mask;
|
|
|
|
void *data;
|
|
};
|
|
#define to_rmi_function_container(d) \
|
|
container_of(d, struct rmi_function_container, dev);
|
|
|
|
|
|
/**
|
|
* struct rmi_driver - represents an RMI driver
|
|
* @driver: Device driver model driver
|
|
* @probe: Callback for device probe
|
|
* @remove: Callback for device removal
|
|
* @shutdown: Callback for device shutdown
|
|
* @irq_handler: Callback for handling irqs
|
|
* @fh_add: Callback for function handler add
|
|
* @fh_remove: Callback for function handler remove
|
|
* @get_func_irq_mask: Callback for calculating interrupt mask
|
|
* @store_irq_mask: Callback for storing and replacing interrupt mask
|
|
* @restore_irq_mask: Callback for restoring previously stored interrupt mask
|
|
* @data: Private data pointer
|
|
*
|
|
* The RMI driver implements a driver on the RMI bus.
|
|
*
|
|
*/
|
|
struct rmi_driver {
|
|
struct device_driver driver;
|
|
|
|
int (*probe)(struct rmi_device *rmi_dev);
|
|
int (*remove)(struct rmi_device *rmi_dev);
|
|
void (*shutdown)(struct rmi_device *rmi_dev);
|
|
int (*irq_handler)(struct rmi_device *rmi_dev, int irq);
|
|
int (*reset_handler)(struct rmi_device *rmi_dev);
|
|
void (*fh_add)(struct rmi_device *rmi_dev,
|
|
struct rmi_function_handler *fh);
|
|
void (*fh_remove)(struct rmi_device *rmi_dev,
|
|
struct rmi_function_handler *fh);
|
|
u8* (*get_func_irq_mask)(struct rmi_device *rmi_dev,
|
|
struct rmi_function_container *fc);
|
|
int (*store_irq_mask)(struct rmi_device *rmi_dev, u8* new_interupts);
|
|
int (*restore_irq_mask)(struct rmi_device *rmi_dev);
|
|
void *data;
|
|
};
|
|
#define to_rmi_driver(d) \
|
|
container_of(d, struct rmi_driver, driver);
|
|
|
|
/** struct rmi_phys_info - diagnostic information about the RMI physical
|
|
* device, used in the phys sysfs file.
|
|
* @proto String indicating the protocol being used.
|
|
* @tx_count Number of transmit operations.
|
|
* @tx_bytes Number of bytes transmitted.
|
|
* @tx_errs Number of errors encountered during transmit operations.
|
|
* @rx_count Number of receive operations.
|
|
* @rx_bytes Number of bytes received.
|
|
* @rx_errs Number of errors encountered during receive operations.
|
|
* @att_count Number of times ATTN assertions have been handled.
|
|
*/
|
|
struct rmi_phys_info {
|
|
char *proto;
|
|
long tx_count;
|
|
long tx_bytes;
|
|
long tx_errs;
|
|
long rx_count;
|
|
long rx_bytes;
|
|
long rx_errs;
|
|
long attn_count;
|
|
};
|
|
|
|
/**
|
|
* struct rmi_phys_device - represent an RMI physical device
|
|
* @dev: Pointer to the communication device, e.g. i2c or spi
|
|
* @rmi_dev: Pointer to the RMI device
|
|
* @write: Callback for write
|
|
* @write_block: Callback for writing a block of data
|
|
* @read: Callback for read
|
|
* @read_block: Callback for reading a block of data
|
|
* @data: Private data pointer
|
|
*
|
|
* The RMI physical device implements the glue between different communication
|
|
* buses such as I2C and SPI.
|
|
*
|
|
*/
|
|
struct rmi_phys_device {
|
|
struct device *dev;
|
|
struct rmi_device *rmi_dev;
|
|
|
|
int (*write)(struct rmi_phys_device *phys, u16 addr, u8 data);
|
|
int (*write_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
|
|
int len);
|
|
int (*read)(struct rmi_phys_device *phys, u16 addr, u8 *buf);
|
|
int (*read_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
|
|
int len);
|
|
|
|
int (*enable_device) (struct rmi_phys_device *phys);
|
|
void (*disable_device) (struct rmi_phys_device *phys);
|
|
|
|
void *data;
|
|
|
|
struct rmi_phys_info info;
|
|
};
|
|
|
|
/**
|
|
* struct rmi_device - represents an RMI device
|
|
* @dev: The device created for the RMI bus
|
|
* @number: Unique number for the device on the bus.
|
|
* @driver: Pointer to associated driver
|
|
* @phys: Pointer to the physical interface
|
|
* @early_suspend_handler: Pointers to early_suspend and late_resume, if
|
|
* configured.
|
|
*
|
|
* This structs represent an RMI device.
|
|
*
|
|
*/
|
|
struct rmi_device {
|
|
struct device dev;
|
|
int number;
|
|
|
|
struct rmi_driver *driver;
|
|
struct rmi_phys_device *phys;
|
|
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
struct early_suspend early_suspend_handler;
|
|
#endif
|
|
#ifdef CONFIG_RMI4_DEBUG
|
|
struct dentry *debugfs_root;
|
|
#endif
|
|
};
|
|
#define to_rmi_device(d) container_of(d, struct rmi_device, dev);
|
|
#define to_rmi_platform_data(d) ((d)->phys->dev->platform_data);
|
|
|
|
static inline void rmi_set_driverdata(struct rmi_device *d, void *data)
|
|
{
|
|
dev_set_drvdata(&d->dev, data);
|
|
}
|
|
|
|
static inline void *rmi_get_driverdata(struct rmi_device *d)
|
|
{
|
|
return dev_get_drvdata(&d->dev);
|
|
}
|
|
|
|
/**
|
|
* rmi_read - RMI read byte
|
|
* @d: Pointer to an RMI device
|
|
* @addr: The address to read from
|
|
* @buf: The read buffer
|
|
*
|
|
* Reads a byte of data using the underlaying physical protocol in to buf. It
|
|
* returns zero or a negative error code.
|
|
*/
|
|
static inline int rmi_read(struct rmi_device *d, u16 addr, u8 *buf)
|
|
{
|
|
return d->phys->read(d->phys, addr, buf);
|
|
}
|
|
|
|
/**
|
|
* rmi_read_block - RMI read block
|
|
* @d: Pointer to an RMI device
|
|
* @addr: The start address to read from
|
|
* @buf: The read buffer
|
|
* @len: Length of the read buffer
|
|
*
|
|
* Reads a block of byte data using the underlaying physical protocol in to buf.
|
|
* It returns the amount of bytes read or a negative error code.
|
|
*/
|
|
static inline int rmi_read_block(struct rmi_device *d, u16 addr, u8 *buf,
|
|
int len)
|
|
{
|
|
return d->phys->read_block(d->phys, addr, buf, len);
|
|
}
|
|
|
|
/**
|
|
* rmi_write - RMI write byte
|
|
* @d: Pointer to an RMI device
|
|
* @addr: The address to write to
|
|
* @data: The data to write
|
|
*
|
|
* Writes a byte from buf using the underlaying physical protocol. It
|
|
* returns zero or a negative error code.
|
|
*/
|
|
static inline int rmi_write(struct rmi_device *d, u16 addr, u8 data)
|
|
{
|
|
return d->phys->write(d->phys, addr, data);
|
|
}
|
|
|
|
/**
|
|
* rmi_write_block - RMI write block
|
|
* @d: Pointer to an RMI device
|
|
* @addr: The start address to write to
|
|
* @buf: The write buffer
|
|
* @len: Length of the write buffer
|
|
*
|
|
* Writes a block of byte data from buf using the underlaying physical protocol.
|
|
* It returns the amount of bytes written or a negative error code.
|
|
*/
|
|
static inline int rmi_write_block(struct rmi_device *d, u16 addr, u8 *buf,
|
|
int len)
|
|
{
|
|
return d->phys->write_block(d->phys, addr, buf, len);
|
|
}
|
|
|
|
/**
|
|
* rmi_register_driver - register rmi driver
|
|
* @driver: the driver to register
|
|
*
|
|
* This function registers an RMI driver to the RMI bus.
|
|
*/
|
|
int rmi_register_driver(struct rmi_driver *driver);
|
|
|
|
/**
|
|
* rmi_unregister_driver - unregister rmi driver
|
|
* @driver: the driver to unregister
|
|
*
|
|
* This function unregisters an RMI driver to the RMI bus.
|
|
*/
|
|
void rmi_unregister_driver(struct rmi_driver *driver);
|
|
|
|
/**
|
|
* rmi_register_phys_device - register a physical device connection
|
|
* @phys: the physical driver to register
|
|
*
|
|
* This function registers a physical driver to the RMI bus. These drivers
|
|
* provide a communication layer for the drivers connected to the bus, e.g.
|
|
* I2C, SPI and so on.
|
|
*/
|
|
int rmi_register_phys_device(struct rmi_phys_device *phys);
|
|
|
|
/**
|
|
* rmi_unregister_phys_device - unregister a physical device connection
|
|
* @phys: the physical driver to unregister
|
|
*
|
|
* This function unregisters a physical driver from the RMI bus.
|
|
*/
|
|
void rmi_unregister_phys_device(struct rmi_phys_device *phys);
|
|
|
|
/**
|
|
* rmi_register_function_driver - register an RMI function driver
|
|
* @fh: the function handler to register
|
|
*
|
|
* This function registers support for a new RMI function to the bus. All
|
|
* drivers on the bus will be notified of the presence of the new function
|
|
* driver.
|
|
*/
|
|
int rmi_register_function_driver(struct rmi_function_handler *fh);
|
|
|
|
/**
|
|
* rmi_unregister_function_driver - unregister an RMI function driver
|
|
* @fh: the function handler to unregister
|
|
*
|
|
* This function unregisters a RMI function from the RMI bus. All drivers on
|
|
* the bus will be notified of the removal of a function driver.
|
|
*/
|
|
void rmi_unregister_function_driver(struct rmi_function_handler *fh);
|
|
|
|
/**
|
|
* rmi_get_function_handler - get a pointer to specified RMI function
|
|
* @id: the RMI function id
|
|
*
|
|
* This function gets the specified RMI function handler from the list of
|
|
* supported functions.
|
|
*/
|
|
struct rmi_function_handler *rmi_get_function_handler(int id);
|
|
|
|
|
|
struct rmi_char_device;
|
|
|
|
/**
|
|
* rmi_char_driver - a general driver that doesn't handle specific functions,
|
|
* operating outside the bus::sensor::functions
|
|
* @match: returns 1 if the driver wants to talk to the specified rmi_dev.
|
|
*
|
|
* All of the above are optional except driver and init which are required.
|
|
*
|
|
*/
|
|
struct rmi_char_driver {
|
|
struct device_driver driver;
|
|
|
|
int (*match)(struct rmi_device *rmi_dev);
|
|
int (*init)(struct rmi_char_device *cd);
|
|
int (*attention)(struct rmi_char_device *cd, u8 *irq_bits);
|
|
#ifdef CONFIG_PM
|
|
int (*suspend)(struct rmi_char_device *cd);
|
|
int (*resume)(struct rmi_char_device *cd);
|
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|
int (*early_suspend)(struct rmi_char_device *cd);
|
|
int (*late_resume)(struct rmi_char_device *cd);
|
|
#endif
|
|
#endif
|
|
void (*remove)(struct rmi_char_device *cd);
|
|
|
|
struct list_head devices;
|
|
};
|
|
|
|
struct rmi_char_device {
|
|
struct list_head list;
|
|
|
|
struct rmi_device *rmi_dev;
|
|
struct rmi_char_driver *driver;
|
|
struct device dev;
|
|
|
|
#ifdef CONFIG_RMI4_DEBUG
|
|
struct dentry *debugfs_root;
|
|
#endif
|
|
|
|
void *data;
|
|
};
|
|
#define to_rmi_char_device(d) \
|
|
container_of(d, struct rmi_char_device, dev)
|
|
|
|
int rmi_register_character_driver(struct rmi_char_driver *char_driver);
|
|
int rmi_unregister_character_driver(struct rmi_char_driver *char_driver);
|
|
|
|
|
|
/* Helper fn to convert a byte array representing a short in the RMI
|
|
* endian-ness to a short in the native processor's specific endianness.
|
|
* We don't use ntohs/htons here because, well, we're not dealing with
|
|
* a pair of shorts. And casting dest to short* wouldn't work, because
|
|
* that would imply knowing the byte order of short in the first place.
|
|
*/
|
|
static inline void batohs(unsigned short *dest, unsigned char *src)
|
|
{
|
|
*dest = src[1] * 0x100 + src[0];
|
|
}
|
|
|
|
/* Helper function to convert a short (in host processor endianess) to
|
|
* a byte array in the RMI endianess for shorts. See above comment for
|
|
* why we dont us htons or something like that.
|
|
*/
|
|
static inline void hstoba(unsigned char *dest, unsigned short src)
|
|
{
|
|
dest[0] = src % 0x100;
|
|
dest[1] = src / 0x100;
|
|
}
|
|
|
|
/* Utility routine to handle writes to read-only attributes. Hopefully
|
|
* this will never happen, but if the user does something stupid, we don't
|
|
* want to accept it quietly (which is what can happen if you just put NULL
|
|
* for the attribute's store function).
|
|
*/
|
|
static inline ssize_t rmi_store_error(struct device *dev,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
dev_warn(dev,
|
|
"RMI4 WARNING: Attempt to write %d characters to read-only "
|
|
"attribute %s.", count, attr->attr.name);
|
|
return -EPERM;
|
|
}
|
|
|
|
/* Utility routine to handle reads of write-only attributes. Hopefully
|
|
* this will never happen, but if the user does something stupid, we don't
|
|
* want to accept it quietly (which is what can happen if you just put NULL
|
|
* for the attribute's show function).
|
|
*/
|
|
static inline ssize_t rmi_show_error(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
dev_warn(dev,
|
|
"RMI4 WARNING: Attempt to read from write-only attribute %s.",
|
|
attr->attr.name);
|
|
return -EPERM;
|
|
}
|
|
|
|
/* utility function for bit access of u8*'s */
|
|
void u8_set_bit(u8 *target, int pos);
|
|
void u8_clear_bit(u8 *target, int pos);
|
|
bool u8_is_set(u8 *target, int pos);
|
|
bool u8_is_any_set(u8 *target, int size);
|
|
void u8_or(u8 *dest, u8* target1, u8* target2, int size);
|
|
void u8_and(u8 *dest, u8* target1, u8* target2, int size);
|
|
#endif
|