Home | History | Annotate | Download | only in wcd9xxx
      1 /* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
      2  *
      3  * This program is free software; you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License version 2 and
      5  * only version 2 as published by the Free Software Foundation.
      6  *
      7  * This program is distributed in the hope that it will be useful,
      8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10  * GNU General Public License for more details.
     11  */
     12 
     13 #ifndef __MFD_TABLA_CORE_H__
     14 #define __MFD_TABLA_CORE_H__
     15 
     16 #include <linux/interrupt.h>
     17 #include <linux/pm_qos.h>
     18 
     19 #define WCD9XXX_NUM_IRQ_REGS 3
     20 
     21 #define WCD9XXX_SLIM_NUM_PORT_REG 3
     22 
     23 #define WCD9XXX_INTERFACE_TYPE_SLIMBUS	0x00
     24 #define WCD9XXX_INTERFACE_TYPE_I2C	0x01
     25 
     26 #define TABLA_VERSION_1_0	0
     27 #define TABLA_VERSION_1_1	1
     28 #define TABLA_VERSION_2_0	2
     29 #define TABLA_IS_1_X(ver) \
     30 	(((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
     31 #define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
     32 
     33 #define SITAR_VERSION_1P0 0
     34 #define SITAR_VERSION_1P1 1
     35 #define SITAR_IS_1P0(ver) \
     36 	((ver == SITAR_VERSION_1P0) ? 1 : 0)
     37 #define SITAR_IS_1P1(ver) \
     38 	((ver == SITAR_VERSION_1P1) ? 1 : 0)
     39 
     40 enum {
     41 	TABLA_IRQ_SLIMBUS = 0,
     42 	TABLA_IRQ_MBHC_REMOVAL,
     43 	TABLA_IRQ_MBHC_SHORT_TERM,
     44 	TABLA_IRQ_MBHC_PRESS,
     45 	TABLA_IRQ_MBHC_RELEASE,
     46 	TABLA_IRQ_MBHC_POTENTIAL,
     47 	TABLA_IRQ_MBHC_INSERTION,
     48 	TABLA_IRQ_BG_PRECHARGE,
     49 	TABLA_IRQ_PA1_STARTUP,
     50 	TABLA_IRQ_PA2_STARTUP,
     51 	TABLA_IRQ_PA3_STARTUP,
     52 	TABLA_IRQ_PA4_STARTUP,
     53 	TABLA_IRQ_PA5_STARTUP,
     54 	TABLA_IRQ_MICBIAS1_PRECHARGE,
     55 	TABLA_IRQ_MICBIAS2_PRECHARGE,
     56 	TABLA_IRQ_MICBIAS3_PRECHARGE,
     57 	TABLA_IRQ_HPH_PA_OCPL_FAULT,
     58 	TABLA_IRQ_HPH_PA_OCPR_FAULT,
     59 	TABLA_IRQ_EAR_PA_OCPL_FAULT,
     60 	TABLA_IRQ_HPH_L_PA_STARTUP,
     61 	TABLA_IRQ_HPH_R_PA_STARTUP,
     62 	TABLA_IRQ_EAR_PA_STARTUP,
     63 	TABLA_NUM_IRQS,
     64 };
     65 
     66 enum {
     67 	SITAR_IRQ_SLIMBUS = 0,
     68 	SITAR_IRQ_MBHC_REMOVAL,
     69 	SITAR_IRQ_MBHC_SHORT_TERM,
     70 	SITAR_IRQ_MBHC_PRESS,
     71 	SITAR_IRQ_MBHC_RELEASE,
     72 	SITAR_IRQ_MBHC_POTENTIAL,
     73 	SITAR_IRQ_MBHC_INSERTION,
     74 	SITAR_IRQ_BG_PRECHARGE,
     75 	SITAR_IRQ_PA1_STARTUP,
     76 	SITAR_IRQ_PA2_STARTUP,
     77 	SITAR_IRQ_PA3_STARTUP,
     78 	SITAR_IRQ_PA4_STARTUP,
     79 	SITAR_IRQ_PA5_STARTUP,
     80 	SITAR_IRQ_MICBIAS1_PRECHARGE,
     81 	SITAR_IRQ_MICBIAS2_PRECHARGE,
     82 	SITAR_IRQ_MICBIAS3_PRECHARGE,
     83 	SITAR_IRQ_HPH_PA_OCPL_FAULT,
     84 	SITAR_IRQ_HPH_PA_OCPR_FAULT,
     85 	SITAR_IRQ_EAR_PA_OCPL_FAULT,
     86 	SITAR_IRQ_HPH_L_PA_STARTUP,
     87 	SITAR_IRQ_HPH_R_PA_STARTUP,
     88 	SITAR_IRQ_EAR_PA_STARTUP,
     89 	SITAR_NUM_IRQS,
     90 };
     91 
     92 
     93 enum {
     94 	TAIKO_IRQ_SLIMBUS = 0,
     95 	TAIKO_IRQ_MBHC_REMOVAL,
     96 	TAIKO_IRQ_MBHC_SHORT_TERM,
     97 	TAIKO_IRQ_MBHC_PRESS,
     98 	TAIKO_IRQ_MBHC_RELEASE,
     99 	TAIKO_IRQ_MBHC_POTENTIAL,
    100 	TAIKO_IRQ_MBHC_INSERTION,
    101 	TAIKO_IRQ_BG_PRECHARGE,
    102 	TAIKO_IRQ_PA1_STARTUP,
    103 	TAIKO_IRQ_PA2_STARTUP,
    104 	TAIKO_IRQ_PA3_STARTUP,
    105 	TAIKO_IRQ_PA4_STARTUP,
    106 	TAIKO_IRQ_PA5_STARTUP,
    107 	TAIKO_IRQ_MICBIAS1_PRECHARGE,
    108 	TAIKO_IRQ_MICBIAS2_PRECHARGE,
    109 	TAIKO_IRQ_MICBIAS3_PRECHARGE,
    110 	TAIKO_IRQ_HPH_PA_OCPL_FAULT,
    111 	TAIKO_IRQ_HPH_PA_OCPR_FAULT,
    112 	TAIKO_IRQ_EAR_PA_OCPL_FAULT,
    113 	TAIKO_IRQ_HPH_L_PA_STARTUP,
    114 	TAIKO_IRQ_HPH_R_PA_STARTUP,
    115 	TAIKO_IRQ_EAR_PA_STARTUP,
    116 	TAIKO_NUM_IRQS,
    117 };
    118 
    119 enum wcd9xxx_pm_state {
    120 	WCD9XXX_PM_SLEEPABLE,
    121 	WCD9XXX_PM_AWAKE,
    122 	WCD9XXX_PM_ASLEEP,
    123 };
    124 
    125 struct wcd9xxx {
    126 	struct device *dev;
    127 	struct slim_device *slim;
    128 	struct slim_device *slim_slave;
    129 	struct mutex io_lock;
    130 	struct mutex xfer_lock;
    131 	struct mutex irq_lock;
    132 	u8 version;
    133 
    134 	unsigned int irq_base;
    135 	unsigned int irq;
    136 	u8 irq_masks_cur[WCD9XXX_NUM_IRQ_REGS];
    137 	u8 irq_masks_cache[WCD9XXX_NUM_IRQ_REGS];
    138 	u8 irq_level[WCD9XXX_NUM_IRQ_REGS];
    139 
    140 	int reset_gpio;
    141 
    142 	int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
    143 			int bytes, void *dest, bool interface_reg);
    144 	int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
    145 			 int bytes, void *src, bool interface_reg);
    146 
    147 	u32 num_of_supplies;
    148 	struct regulator_bulk_data *supplies;
    149 
    150 	enum wcd9xxx_pm_state pm_state;
    151 	struct mutex pm_lock;
    152 	/* pm_wq notifies change of pm_state */
    153 	wait_queue_head_t pm_wq;
    154 	struct pm_qos_request pm_qos_req;
    155 	int wlock_holders;
    156 
    157 	int num_rx_port;
    158 	int num_tx_port;
    159 
    160 	u8 idbyte[4];
    161 };
    162 
    163 int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
    164 int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
    165 		u8 val);
    166 int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
    167 int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
    168 		u8 val);
    169 int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
    170 			int count, u8 *buf);
    171 int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
    172 			int count, u8 *buf);
    173 int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx);
    174 void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx);
    175 int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
    176 int wcd9xxx_get_intf_type(void);
    177 
    178 bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
    179 void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
    180 enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
    181 				enum wcd9xxx_pm_state o,
    182 				enum wcd9xxx_pm_state n);
    183 
    184 static inline int wcd9xxx_request_irq(struct wcd9xxx *wcd9xxx, int irq,
    185 				     irq_handler_t handler, const char *name,
    186 				     void *data)
    187 {
    188 	if (!wcd9xxx->irq_base)
    189 		return -EINVAL;
    190 	return request_threaded_irq(wcd9xxx->irq_base + irq, NULL, handler,
    191 				    IRQF_TRIGGER_RISING, name,
    192 				    data);
    193 }
    194 static inline void wcd9xxx_free_irq(struct wcd9xxx *wcd9xxx,
    195 				int irq, void *data)
    196 {
    197 	if (!wcd9xxx->irq_base)
    198 		return;
    199 	free_irq(wcd9xxx->irq_base + irq, data);
    200 }
    201 static inline void wcd9xxx_enable_irq(struct wcd9xxx *wcd9xxx, int irq)
    202 {
    203 	if (!wcd9xxx->irq_base)
    204 		return;
    205 	enable_irq(wcd9xxx->irq_base + irq);
    206 }
    207 static inline void wcd9xxx_disable_irq(struct wcd9xxx *wcd9xxx, int irq)
    208 {
    209 	if (!wcd9xxx->irq_base)
    210 		return;
    211 	disable_irq_nosync(wcd9xxx->irq_base + irq);
    212 }
    213 static inline void wcd9xxx_disable_irq_sync(struct wcd9xxx *wcd9xxx, int irq)
    214 {
    215 	if (!wcd9xxx->irq_base)
    216 		return;
    217 	disable_irq(wcd9xxx->irq_base + irq);
    218 }
    219 
    220 #endif
    221