/* * 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 #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_HAS_EARLYSUSPEND #include #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 SYNAPTICS_RMI_NAME "rmi-i2c" #define SYNAPTICS_RMI_ADDR 0x20 #define PDT_START_SCAN_LOCATION 0x00e9 enum rmi_attn_polarity { RMI_ATTN_ACTIVE_LOW = 0, RMI_ATTN_ACTIVE_HIGH = 1 }; /** * struct rmi_f11_axis_alignmen - 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_f19_button_map { unsigned char nbuttons; unsigned char *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; 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_f11_2d_axis_alignment axis_align; struct rmi_f19_button_map *button_map; #ifdef CONFIG_PM void *pm_data; int (*pre_suspend) (const void *pm_data); int (*post_resume) (const void *pm_data); #endif void (*hw_reset) (void); }; /** * 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; 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 }; #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; 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