#ifndef __MFD_WM831X_CORE_H__
#define __MFD_WM831X_CORE_H__
+#include <linux/completion.h>
#include <linux/interrupt.h>
-#include <linux/workqueue.h>
+#include <linux/wakelock.h>
+#include <linux/regulator/driver.h>
/*
* Register values.
#define WM831X_DC3_SLEEP_CONTROL 0x4063
#define WM831X_DC4_CONTROL 0x4064
#define WM831X_DC4_SLEEP_CONTROL 0x4065
+#define WM832X_DC4_SLEEP_CONTROL 0x4067
#define WM831X_EPE1_CONTROL 0x4066
#define WM831X_EPE2_CONTROL 0x4067
#define WM831X_LDO1_CONTROL 0x4068
struct regulator_dev;
+#define WM831X_NUM_IRQ_REGS 5
+#define WM831X_IRQ_LIST 1
+enum wm831x_parent {
+ WM8310 = 0x8310,
+ WM8311 = 0x8311,
+ WM8312 = 0x8312,
+ WM8320 = 0x8320,
+ WM8321 = 0x8321,
+ WM8325 = 0x8325,
+};
+
struct wm831x {
struct mutex io_lock;
struct mutex irq_lock;
struct workqueue_struct *irq_wq;
struct work_struct irq_work;
+ struct wake_lock irq_wake;
+ struct wake_lock handle_wake;
+#if WM831X_IRQ_LIST
+ struct workqueue_struct *handle_wq;
+ struct work_struct handle_work;
+ spinlock_t work_lock;
+ struct list_head handle_queue;
+#endif
unsigned int irq_base;
- int irq_masks[5];
+ int irq_masks_cur[WM831X_NUM_IRQ_REGS]; /* Currently active value */
+ int irq_masks_cache[WM831X_NUM_IRQ_REGS]; /* Cached hardware value */
+
+ /* Chip revision based flags */
+ unsigned has_gpio_ena:1; /* Has GPIO enable bit */
+ unsigned has_cs_sts:1; /* Has current sink status bit */
+ unsigned charger_irq_wake:1; /* Are charger IRQs a wake source? */
+
+ int num_gpio;
struct mutex auxadc_lock;
+ struct completion auxadc_done;
/* The WM831x has a security key blocking access to certain
* registers. The mutex is taken by the accessors for locking
unsigned int locked:1;
};
+#define WM831X_DCDC_MAX_NAME 6
+#define WM831X_LDO_MAX_NAME 6
+#define WM831X_ISINK_MAX_NAME 7
+
+struct wm831x_dcdc {
+ char name[WM831X_DCDC_MAX_NAME];
+ struct regulator_desc desc;
+ int base;
+ struct wm831x *wm831x;
+ struct regulator_dev *regulator;
+ int dvs_gpio;
+ int dvs_gpio_state;
+ int on_vsel;
+ int dvs_vsel;
+};
+
+struct wm831x_ldo {
+ char name[WM831X_LDO_MAX_NAME];
+ struct regulator_desc desc;
+ int base;
+ struct wm831x *wm831x;
+ struct regulator_dev *regulator;
+};
+
+struct wm831x_isink {
+ char name[WM831X_ISINK_MAX_NAME];
+ struct regulator_desc desc;
+ int reg;
+ struct wm831x *wm831x;
+ struct regulator_dev *regulator;
+};
+
+
/* Device I/O API */
int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg);
int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
int count, u16 *buf);
+int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
+void wm831x_device_exit(struct wm831x *wm831x);
+int wm831x_device_suspend(struct wm831x *wm831x);
+int wm831x_device_resume(struct wm831x *wm831x);
+int wm831x_device_shutdown(struct wm831x *wm831x);
int wm831x_irq_init(struct wm831x *wm831x, int irq);
void wm831x_irq_exit(struct wm831x *wm831x);
-int __must_check wm831x_request_irq(struct wm831x *wm831x,
- unsigned int irq, irq_handler_t handler,
- unsigned long flags, const char *name,
- void *dev);
-void wm831x_free_irq(struct wm831x *wm831x, unsigned int, void *);
-void wm831x_disable_irq(struct wm831x *wm831x, int irq);
-void wm831x_enable_irq(struct wm831x *wm831x, int irq);
+static inline int __must_check wm831x_request_irq(struct wm831x *wm831x,
+ unsigned int irq,
+ irq_handler_t handler,
+ unsigned long flags,
+ const char *name,
+ void *dev)
+{
+ return request_threaded_irq(irq, NULL, handler, flags, name, dev);
+}
+
+static inline void wm831x_free_irq(struct wm831x *wm831x,
+ unsigned int irq, void *dev)
+{
+ free_irq(irq, dev);
+}
+
+static inline void wm831x_disable_irq(struct wm831x *wm831x, int irq)
+{
+ disable_irq(irq);
+}
+
+static inline void wm831x_enable_irq(struct wm831x *wm831x, int irq)
+{
+ enable_irq(irq);
+}
#endif
#define WM831X_GP1_EINT_SHIFT 0 /* GP1_EINT */
#define WM831X_GP1_EINT_WIDTH 1 /* GP1_EINT */
+
/*
- * R16407 (0x4017) - IRQ Config
+ * Reg (0x4017) - IRQ Config
*/
-#define WM831X_IRQ_OD 0x0002 /* IRQ_OD */
-#define WM831X_IRQ_OD_MASK 0x0002 /* IRQ_OD */
-#define WM831X_IRQ_OD_SHIFT 1 /* IRQ_OD */
-#define WM831X_IRQ_OD_WIDTH 1 /* IRQ_OD */
-#define WM831X_IM_IRQ 0x0001 /* IM_IRQ */
-#define WM831X_IM_IRQ_MASK 0x0001 /* IM_IRQ */
-#define WM831X_IM_IRQ_SHIFT 0 /* IM_IRQ */
-#define WM831X_IM_IRQ_WIDTH 1 /* IM_IRQ */
+ #define WM831X_IRQ_OD_ENABLE 0x0002 /* CMOS/open drain */
+#define WM831X_IRQ_OD_MASK 0x0002 /* CMOS/open drain */
+#define WM831X_IRQ_OD_SHIFT 2 /* CMOS/open drain */
+#define WM831X_IRQ_IM_EANBLE 0x0001 /* IM_IRQ */
+#define WM831X_IRQ_IM_MASK 0x0001 /* IM_IRQ */
+#define WM831X_IRQ_IM_SHIFT 0 /* IM_IRQ */
+
/*
* R16408 (0x4018) - System Interrupts Mask
int eoc_iterm; /** End of trickle charge current, in mA */
int fast_ilim; /** Fast charge current limit, in mA */
int timeout; /** Charge cycle timeout, in minutes */
+ int syslo; /** syslo threshold, in mV**/
+ int sysok; /** sysok threshold, in mV**/
+};
+
+/**
+ * Configuration for the WM831x DC-DC BuckWise convertors. This
+ * should be passed as driver_data in the regulator_init_data.
+ *
+ * Currently all the configuration is for the fast DVS switching
+ * support of the devices. This allows MFPs on the device to be
+ * configured as an input to switch between two output voltages,
+ * allowing voltage transitions without the expense of an access over
+ * I2C or SPI buses.
+ */
+struct wm831x_buckv_pdata {
+ int dvs_gpio; /** CPU GPIO to use for DVS switching */
+ int dvs_control_src; /** Hardware DVS source to use (1 or 2) */
+ int dvs_init_state; /** DVS state to expect on startup */
+ int dvs_state_gpio; /** CPU GPIO to use for monitoring status */
};
/* Sources for status LED configuration. Values are register values
int update_gpio;
unsigned int software:1;
};
+struct wm831x_gpio_keys_button {
+ /* Configuration parameters */
+ int code; /* input event code (KEY_*, SW_*) */
+ int gpio;
+ int active_low;
+ char *desc;
+ int type; /* input event type (EV_KEY, EV_SW) */
+ int wakeup; /* configure the button as a wake-up source */
+ int debounce_interval; /* debounce ticks interval in msecs */
+};
+
+struct wm831x_gpio_keys_pdata {
+ struct wm831x_gpio_keys_button *buttons;
+ int nbuttons;
+ unsigned int rep:1; /* enable input subsystem auto repeat */
+};
#define WM831X_MAX_STATUS 2
#define WM831X_MAX_DCDC 4
int (*pre_init)(struct wm831x *wm831x);
/** Called after subdevices are set up */
int (*post_init)(struct wm831x *wm831x);
-
+ /** Called before subdevices are power down */
+ int (*last_deinit)(struct wm831x *wm831x);
+ //add by sxj
+ unsigned int gpio_pin_num;
+ struct rk2818_gpio_expander_info *settinginfo;
+ int settinginfolen;
+ int (*pin_type_init)(struct wm831x *wm831x);
+ //above add by sxj
+ int irq_base;
int gpio_base;
struct wm831x_backlight_pdata *backlight;
struct wm831x_backup_pdata *backup;
struct wm831x_battery_pdata *battery;
struct wm831x_touch_pdata *touch;
struct wm831x_watchdog_pdata *watchdog;
+ //add by srt
+ struct wm831x_gpio_keys_pdata *gpio_keys;
+ //end by srt
/** LED1 = 0 and so on */
struct wm831x_status_pdata *status[WM831X_MAX_STATUS];