blob: 37a12fb627f118c9d17b1d7475728cb8a7381bdf [file] [log] [blame]
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08001/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05302 *
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
Kuirong Wang906ac472012-07-09 12:54:44 -070016#include <linux/types.h>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053017#include <linux/interrupt.h>
Stephen Boyd2fcabf92012-05-30 10:41:11 -070018#include <linux/pm_qos.h>
Joonwoo Parkf6574c72012-10-10 17:29:57 -070019#include <linux/platform_device.h>
20#include <linux/of_irq.h>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053021
Joonwoo Parka8890262012-10-15 12:04:27 -070022#define WCD9XXX_NUM_IRQ_REGS 4
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053023
24#define WCD9XXX_SLIM_NUM_PORT_REG 3
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053025#define TABLA_VERSION_1_0 0
26#define TABLA_VERSION_1_1 1
27#define TABLA_VERSION_2_0 2
28#define TABLA_IS_1_X(ver) \
29 (((ver == TABLA_VERSION_1_0) || (ver == TABLA_VERSION_1_1)) ? 1 : 0)
30#define TABLA_IS_2_0(ver) ((ver == TABLA_VERSION_2_0) ? 1 : 0)
31
Bhalchandra Gajare87fef4c2013-02-19 14:57:03 -080032#define WCD9XXX_SUPPLY_BUCK_NAME "cdc-vdd-buck"
33
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -070034#define SITAR_VERSION_1P0 0
35#define SITAR_VERSION_1P1 1
36#define SITAR_IS_1P0(ver) \
37 ((ver == SITAR_VERSION_1P0) ? 1 : 0)
38#define SITAR_IS_1P1(ver) \
39 ((ver == SITAR_VERSION_1P1) ? 1 : 0)
40
Joonwoo Park3cf3a942013-02-13 14:18:22 -080041#define TAIKO_VERSION_1_0 1
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -070042#define TAIKO_IS_1_0(ver) \
43 ((ver == TAIKO_VERSION_1_0) ? 1 : 0)
44
Bhalchandra Gajare750d12d2013-03-01 20:56:36 -080045#define TAPAN_VERSION_1_0 0
46#define TAPAN_IS_1_0(ver) \
47 ((ver == TAPAN_VERSION_1_0) ? 1 : 0)
48
Joonwoo Park3cf3a942013-02-13 14:18:22 -080049enum wcd9xxx_slim_slave_addr_type {
50 WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TABLA,
51 WCD9XXX_SLIM_SLAVE_ADDR_TYPE_TAIKO,
52};
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -070053
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053054enum {
Joonwoo Parka8890262012-10-15 12:04:27 -070055 /* INTR_REG 0 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070056 WCD9XXX_IRQ_SLIMBUS = 0,
57 WCD9XXX_IRQ_MBHC_REMOVAL,
58 WCD9XXX_IRQ_MBHC_SHORT_TERM,
59 WCD9XXX_IRQ_MBHC_PRESS,
60 WCD9XXX_IRQ_MBHC_RELEASE,
61 WCD9XXX_IRQ_MBHC_POTENTIAL,
62 WCD9XXX_IRQ_MBHC_INSERTION,
63 WCD9XXX_IRQ_BG_PRECHARGE,
Joonwoo Parka8890262012-10-15 12:04:27 -070064 /* INTR_REG 1 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070065 WCD9XXX_IRQ_PA1_STARTUP,
66 WCD9XXX_IRQ_PA2_STARTUP,
67 WCD9XXX_IRQ_PA3_STARTUP,
68 WCD9XXX_IRQ_PA4_STARTUP,
69 WCD9XXX_IRQ_PA5_STARTUP,
70 WCD9XXX_IRQ_MICBIAS1_PRECHARGE,
71 WCD9XXX_IRQ_MICBIAS2_PRECHARGE,
72 WCD9XXX_IRQ_MICBIAS3_PRECHARGE,
Joonwoo Parka8890262012-10-15 12:04:27 -070073 /* INTR_REG 2 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070074 WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
75 WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
76 WCD9XXX_IRQ_EAR_PA_OCPL_FAULT,
77 WCD9XXX_IRQ_HPH_L_PA_STARTUP,
78 WCD9XXX_IRQ_HPH_R_PA_STARTUP,
79 WCD9XXX_IRQ_EAR_PA_STARTUP,
Joonwoo Parka8890262012-10-15 12:04:27 -070080 WCD9XXX_IRQ_RESERVED_0,
81 WCD9XXX_IRQ_RESERVED_1,
82 /* INTR_REG 3 */
83 WCD9XXX_IRQ_MAD_AUDIO,
84 WCD9XXX_IRQ_MAD_BEACON,
85 WCD9XXX_IRQ_MAD_ULTRASOUND,
86 WCD9XXX_IRQ_SPEAKER_CLIPPING,
87 WCD9XXX_IRQ_MBHC_JACK_SWITCH,
Joonwoo Parkf6574c72012-10-10 17:29:57 -070088 WCD9XXX_NUM_IRQS,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053089};
90
91enum {
Joonwoo Parkf6574c72012-10-10 17:29:57 -070092 TABLA_NUM_IRQS = WCD9XXX_NUM_IRQS,
93 SITAR_NUM_IRQS = WCD9XXX_NUM_IRQS,
94 TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS,
Banajit Goswami4d6d891b2012-12-12 23:59:07 -080095 TAPAN_NUM_IRQS = WCD9XXX_NUM_IRQS,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053096};
97
98
Joonwoo Parkf6574c72012-10-10 17:29:57 -070099#define MAX(X, Y) (((int)X) >= ((int)Y) ? (X) : (Y))
100#define WCD9XXX_MAX_NUM_IRQS (MAX(MAX(TABLA_NUM_IRQS, SITAR_NUM_IRQS), \
101 TAIKO_NUM_IRQS))
Kiran Kandic3b24402012-06-11 00:05:59 -0700102
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530103enum wcd9xxx_pm_state {
104 WCD9XXX_PM_SLEEPABLE,
105 WCD9XXX_PM_AWAKE,
106 WCD9XXX_PM_ASLEEP,
107};
108
Kuirong Wang906ac472012-07-09 12:54:44 -0700109/*
110 * data structure for Slimbus and I2S channel.
111 * Some of fields are only used in smilbus mode
112 */
113struct wcd9xxx_ch {
114 u32 sph; /* share channel handle - slimbus only */
115 u32 ch_num; /*
116 * vitrual channel number, such as 128 -144.
117 * apply for slimbus only
118 */
119 u16 ch_h; /* chanel handle - slimbus only */
120 u16 port; /*
121 * tabla port for RX and TX
122 * such as 0-9 for TX and 10 -16 for RX
123 * apply for both i2s and slimbus
124 */
125 u16 shift; /*
126 * shift bit for RX and TX
127 * apply for both i2s and slimbus
128 */
129 struct list_head list; /*
130 * channel link list
131 * apply for both i2s and slimbus
132 */
133};
134
135struct wcd9xxx_codec_dai_data {
136 u32 rate; /* sample rate */
137 u32 bit_width; /* sit width 16,24,32 */
138 struct list_head wcd9xxx_ch_list; /* channel list */
139 u16 grph; /* slimbus group handle */
Joonwoo Park9bbb4d12012-11-09 19:58:11 -0800140 unsigned long ch_mask;
Kuirong Wang906ac472012-07-09 12:54:44 -0700141 wait_queue_head_t dai_wait;
142};
143
Venkat Sudhira50a3762012-11-26 12:12:15 -0800144enum wcd9xxx_intf_status {
145 WCD9XXX_INTERFACE_TYPE_PROBING,
146 WCD9XXX_INTERFACE_TYPE_SLIMBUS,
147 WCD9XXX_INTERFACE_TYPE_I2C,
148};
149
Kuirong Wang906ac472012-07-09 12:54:44 -0700150#define WCD9XXX_CH(xport, xshift) \
151 {.port = xport, .shift = xshift}
152
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530153struct wcd9xxx {
154 struct device *dev;
155 struct slim_device *slim;
156 struct slim_device *slim_slave;
157 struct mutex io_lock;
158 struct mutex xfer_lock;
159 struct mutex irq_lock;
Joonwoo Park1f9d7fd2013-01-07 12:40:03 -0800160 struct mutex nested_irq_lock;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530161 u8 version;
162
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530163 int reset_gpio;
164
165 int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
166 int bytes, void *dest, bool interface_reg);
167 int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
Kuirong Wang906ac472012-07-09 12:54:44 -0700168 int bytes, void *src, bool interface_reg);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -0800169 int (*post_reset)(struct wcd9xxx *wcd9xxx);
170
171 void *ssr_priv;
172 bool slim_device_bootup;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530173
Kiran Kandi725f8492012-08-06 13:45:16 -0700174 u32 num_of_supplies;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530175 struct regulator_bulk_data *supplies;
176
177 enum wcd9xxx_pm_state pm_state;
178 struct mutex pm_lock;
179 /* pm_wq notifies change of pm_state */
180 wait_queue_head_t pm_wq;
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700181 struct pm_qos_request pm_qos_req;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530182 int wlock_holders;
Joonwoo Parkd7cf2e92012-03-19 19:38:23 -0700183
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700184 u8 idbyte[4];
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700185
186 unsigned int irq_base;
187 unsigned int irq;
188 u8 irq_masks_cur[WCD9XXX_NUM_IRQ_REGS];
189 u8 irq_masks_cache[WCD9XXX_NUM_IRQ_REGS];
190 bool irq_level_high[WCD9XXX_MAX_NUM_IRQS];
191 int num_irqs;
Kuirong Wang906ac472012-07-09 12:54:44 -0700192 /* Slimbus or I2S port */
193 u32 num_rx_port;
194 u32 num_tx_port;
195 struct wcd9xxx_ch *rx_chs;
196 struct wcd9xxx_ch *tx_chs;
Venkat Sudhira50a3762012-11-26 12:12:15 -0800197 u32 mclk_rate;
Joonwoo Park3cf3a942013-02-13 14:18:22 -0800198
199 enum wcd9xxx_slim_slave_addr_type slim_slave_type;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530200};
201
202int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
203int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
204 u8 val);
205int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
206int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
207 u8 val);
208int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
209 int count, u8 *buf);
210int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
211 int count, u8 *buf);
212int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx);
213void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx);
214int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
Venkat Sudhira50a3762012-11-26 12:12:15 -0800215enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530216
Joonwoo Parkd7cf2e92012-03-19 19:38:23 -0700217bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530218void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
Joonwoo Park1f9d7fd2013-01-07 12:40:03 -0800219void wcd9xxx_nested_irq_lock(struct wcd9xxx *wcd9xxx);
220void wcd9xxx_nested_irq_unlock(struct wcd9xxx *wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530221enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
222 enum wcd9xxx_pm_state o,
223 enum wcd9xxx_pm_state n);
224
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700225int wcd9xxx_request_irq(struct wcd9xxx *wcd9xxx, int irq,
226 irq_handler_t handler, const char *name, void *data);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530227
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700228void wcd9xxx_free_irq(struct wcd9xxx *wcd9xxx, int irq, void *data);
229void wcd9xxx_enable_irq(struct wcd9xxx *wcd9xxx, int irq);
230void wcd9xxx_disable_irq(struct wcd9xxx *wcd9xxx, int irq);
231void wcd9xxx_disable_irq_sync(struct wcd9xxx *wcd9xxx, int irq);
Rohit Vaswani750bee12012-09-20 16:18:10 -0700232#if defined(CONFIG_WCD9310_CODEC) || \
233 defined(CONFIG_WCD9304_CODEC) || \
Banajit Goswami4d6d891b2012-12-12 23:59:07 -0800234 defined(CONFIG_WCD9320_CODEC) || \
235 defined(CONFIG_WCD9306_CODEC)
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700236int __init wcd9xxx_irq_of_init(struct device_node *node,
237 struct device_node *parent);
Rohit Vaswani750bee12012-09-20 16:18:10 -0700238#else
239static inline int __init wcd9xxx_irq_of_init(struct device_node *node,
240 struct device_node *parent)
241{
242 return 0;
243}
Banajit Goswami4d6d891b2012-12-12 23:59:07 -0800244#endif /* CONFIG_OF */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530245#endif