/* * 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 #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_irq_polarity { RMI_IRQ_ACTIVE_LOW = 0, RMI_IRQ_ACTIVE_HIGH = 1 }; 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; }; union rmi_f11_2d_ctrl0 { struct { u8 reporting_mode:3; u8 abs_pos_filt:1; u8 rel_pos_filt:1; u8 rel_ballistics:1; u8 dribble:1; u8 report_beyond_clip:1; }; u8 reg; }; union rmi_f11_2d_ctrl1 { struct { u8 palm_detect_thres:4; u8 motion_sensitivity:2; u8 man_track_en:1; u8 man_tracked_finger:1; }; u8 reg; }; union rmi_f11_2d_ctrl2__3 { struct { u8 delta_x_threshold:8; u8 delta_y_threshold:8; }; u8 regs[2]; }; union rmi_f11_2d_ctrl4 { struct { u8 velocity:8; }; u8 reg; }; union rmi_f11_2d_ctrl5 { struct { u8 acceleration:8; }; u8 reg; }; union rmi_f11_2d_ctrl6__7 { struct { u16 sensor_max_x_pos:12; }; u8 regs[2]; }; union rmi_f11_2d_ctrl8__9 { struct { u16 sensor_max_y_pos:12; }; u8 regs[2]; }; union rmi_f11_2d_ctrl10 { struct { u8 single_tap_int_enable:1; u8 tap_n_hold_int_enable:1; u8 double_tap_int_enable:1; u8 early_tap_int_enable:1; u8 flick_int_enable:1; u8 press_int_enable:1; u8 pinch_int_enable:1; }; u8 reg; }; union rmi_f11_2d_ctrl11 { struct { u8 palm_detect_int_enable:1; u8 rotate_int_enable:1; u8 touch_shape_int_enable:1; u8 scroll_zone_int_enable:1; u8 multi_finger_scroll_int_enable:1; }; u8 reg; }; union rmi_f11_2d_ctrl12 { struct { u8 sensor_map:7; u8 xy_sel:1; }; u8 reg; }; union rmi_f11_2d_ctrl14 { struct { u8 sens_adjustment:5; u8 hyst_adjustment:3; }; u8 reg; }; struct rmi_f11_2d_ctrl { union rmi_f11_2d_ctrl0 *ctrl0; union rmi_f11_2d_ctrl1 *ctrl1; union rmi_f11_2d_ctrl2__3 *ctrl2__3; union rmi_f11_2d_ctrl4 *ctrl4; union rmi_f11_2d_ctrl5 *ctrl5; union rmi_f11_2d_ctrl6__7 *ctrl6__7; union rmi_f11_2d_ctrl8__9 *ctrl8__9; union rmi_f11_2d_ctrl10 *ctrl10; union rmi_f11_2d_ctrl11 *ctrl11; union rmi_f11_2d_ctrl12 *ctrl12; u8 ctrl12_size; union rmi_f11_2d_ctrl14 *ctrl14; u8 *ctrl15; u8 *ctrl16; u8 *ctrl17; u8 *ctrl18; u8 *ctrl19; }; 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 byte_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; int irq_no; int irq; enum rmi_irq_polarity irq_polarity; int (*gpio_config)(void); struct rmi_device_platform_data_spi spi_v2; struct rmi_f11_2d_ctrl *f11_ctrl; 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 }; 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 { int func; int (*init)(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); #endif void (*remove)(struct rmi_function_container *fc); }; struct rmi_function_device { struct device dev; }; 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); #define to_rmi_function_device(d) \ container_of(d, struct rmi_function_device, dev); #define RMI_CHAR_DEV_TMPBUF_SZ 128 #define RMI_REG_ADDR_PAGE_SELECT 0xFF struct rmi_char_dev { struct mutex mutex_file_op; struct cdev main_dev; struct rmi_phys_device *phys; int ref_count; }; int rmi_char_dev_register(void); void rmi_char_dev_unregister(struct rmi_phys_device *phys); 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); 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 { char *proto; long tx_count; long tx_bytes; long tx_errs; long rx_count; long rx_bytes; long rx_errs; long attn_count; long attn; }; 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_char_dev *char_dev; struct class *rmi_char_device_class; }; struct rmi_device { struct device dev; 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); int i2c_rmi_read(uint16_t addr, uint8_t *data, uint16_t length); int i2c_rmi_write(uint16_t addr, uint8_t *data, uint16_t length); 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); } static inline int rmi_read(struct rmi_device *d, u16 addr, u8 *buf) { return d->phys->read(d->phys, addr, buf); } 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); } static inline int rmi_write(struct rmi_device *d, u16 addr, u8 data) { return d->phys->write(d->phys, addr, data); } 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); } int rmi_register_driver(struct rmi_driver *driver); void rmi_unregister_driver(struct rmi_driver *driver); int rmi_register_phys_device(struct rmi_phys_device *phys); void rmi_unregister_phys_device(struct rmi_phys_device *phys); int rmi_register_function_driver(struct rmi_function_handler *fh); void rmi_unregister_function_driver(struct rmi_function_handler *fh); struct rmi_function_handler *rmi_get_function_handler(int id); ssize_t rmi_store_error(struct device *dev, struct device_attribute *attr, const char *buf, size_t count); ssize_t rmi_show_error(struct device *dev, struct device_attribute *attr, char *buf); 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