blob: 1402fd0a60082879716ce53015467d3e6443b7fa [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 Gajare83c81f62012-05-18 16:09:05 -070032#define SITAR_VERSION_1P0 0
33#define SITAR_VERSION_1P1 1
34#define SITAR_IS_1P0(ver) \
35 ((ver == SITAR_VERSION_1P0) ? 1 : 0)
36#define SITAR_IS_1P1(ver) \
37 ((ver == SITAR_VERSION_1P1) ? 1 : 0)
38
Kiran Kandi7b7d2ff2012-09-14 14:52:14 -070039
40#define TAIKO_VERSION_1_0 0
41#define TAIKO_IS_1_0(ver) \
42 ((ver == TAIKO_VERSION_1_0) ? 1 : 0)
43
44
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053045enum {
Joonwoo Parka8890262012-10-15 12:04:27 -070046 /* INTR_REG 0 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070047 WCD9XXX_IRQ_SLIMBUS = 0,
48 WCD9XXX_IRQ_MBHC_REMOVAL,
49 WCD9XXX_IRQ_MBHC_SHORT_TERM,
50 WCD9XXX_IRQ_MBHC_PRESS,
51 WCD9XXX_IRQ_MBHC_RELEASE,
52 WCD9XXX_IRQ_MBHC_POTENTIAL,
53 WCD9XXX_IRQ_MBHC_INSERTION,
54 WCD9XXX_IRQ_BG_PRECHARGE,
Joonwoo Parka8890262012-10-15 12:04:27 -070055 /* INTR_REG 1 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070056 WCD9XXX_IRQ_PA1_STARTUP,
57 WCD9XXX_IRQ_PA2_STARTUP,
58 WCD9XXX_IRQ_PA3_STARTUP,
59 WCD9XXX_IRQ_PA4_STARTUP,
60 WCD9XXX_IRQ_PA5_STARTUP,
61 WCD9XXX_IRQ_MICBIAS1_PRECHARGE,
62 WCD9XXX_IRQ_MICBIAS2_PRECHARGE,
63 WCD9XXX_IRQ_MICBIAS3_PRECHARGE,
Joonwoo Parka8890262012-10-15 12:04:27 -070064 /* INTR_REG 2 */
Joonwoo Parkf6574c72012-10-10 17:29:57 -070065 WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
66 WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
67 WCD9XXX_IRQ_EAR_PA_OCPL_FAULT,
68 WCD9XXX_IRQ_HPH_L_PA_STARTUP,
69 WCD9XXX_IRQ_HPH_R_PA_STARTUP,
70 WCD9XXX_IRQ_EAR_PA_STARTUP,
Joonwoo Parka8890262012-10-15 12:04:27 -070071 WCD9XXX_IRQ_RESERVED_0,
72 WCD9XXX_IRQ_RESERVED_1,
73 /* INTR_REG 3 */
74 WCD9XXX_IRQ_MAD_AUDIO,
75 WCD9XXX_IRQ_MAD_BEACON,
76 WCD9XXX_IRQ_MAD_ULTRASOUND,
77 WCD9XXX_IRQ_SPEAKER_CLIPPING,
78 WCD9XXX_IRQ_MBHC_JACK_SWITCH,
Joonwoo Parkf6574c72012-10-10 17:29:57 -070079 WCD9XXX_NUM_IRQS,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053080};
81
82enum {
Joonwoo Parkf6574c72012-10-10 17:29:57 -070083 TABLA_NUM_IRQS = WCD9XXX_NUM_IRQS,
84 SITAR_NUM_IRQS = WCD9XXX_NUM_IRQS,
85 TAIKO_NUM_IRQS = WCD9XXX_NUM_IRQS,
Banajit Goswami4d6d891b2012-12-12 23:59:07 -080086 TAPAN_NUM_IRQS = WCD9XXX_NUM_IRQS,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053087};
88
89
Joonwoo Parkf6574c72012-10-10 17:29:57 -070090#define MAX(X, Y) (((int)X) >= ((int)Y) ? (X) : (Y))
91#define WCD9XXX_MAX_NUM_IRQS (MAX(MAX(TABLA_NUM_IRQS, SITAR_NUM_IRQS), \
92 TAIKO_NUM_IRQS))
Kiran Kandic3b24402012-06-11 00:05:59 -070093
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053094enum wcd9xxx_pm_state {
95 WCD9XXX_PM_SLEEPABLE,
96 WCD9XXX_PM_AWAKE,
97 WCD9XXX_PM_ASLEEP,
98};
99
Kuirong Wang906ac472012-07-09 12:54:44 -0700100/*
101 * data structure for Slimbus and I2S channel.
102 * Some of fields are only used in smilbus mode
103 */
104struct wcd9xxx_ch {
105 u32 sph; /* share channel handle - slimbus only */
106 u32 ch_num; /*
107 * vitrual channel number, such as 128 -144.
108 * apply for slimbus only
109 */
110 u16 ch_h; /* chanel handle - slimbus only */
111 u16 port; /*
112 * tabla port for RX and TX
113 * such as 0-9 for TX and 10 -16 for RX
114 * apply for both i2s and slimbus
115 */
116 u16 shift; /*
117 * shift bit for RX and TX
118 * apply for both i2s and slimbus
119 */
120 struct list_head list; /*
121 * channel link list
122 * apply for both i2s and slimbus
123 */
124};
125
126struct wcd9xxx_codec_dai_data {
127 u32 rate; /* sample rate */
128 u32 bit_width; /* sit width 16,24,32 */
129 struct list_head wcd9xxx_ch_list; /* channel list */
130 u16 grph; /* slimbus group handle */
Joonwoo Park9bbb4d12012-11-09 19:58:11 -0800131 unsigned long ch_mask;
Kuirong Wang906ac472012-07-09 12:54:44 -0700132 wait_queue_head_t dai_wait;
133};
134
Venkat Sudhira50a3762012-11-26 12:12:15 -0800135enum wcd9xxx_intf_status {
136 WCD9XXX_INTERFACE_TYPE_PROBING,
137 WCD9XXX_INTERFACE_TYPE_SLIMBUS,
138 WCD9XXX_INTERFACE_TYPE_I2C,
139};
140
Kuirong Wang906ac472012-07-09 12:54:44 -0700141#define WCD9XXX_CH(xport, xshift) \
142 {.port = xport, .shift = xshift}
143
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530144struct wcd9xxx {
145 struct device *dev;
146 struct slim_device *slim;
147 struct slim_device *slim_slave;
148 struct mutex io_lock;
149 struct mutex xfer_lock;
150 struct mutex irq_lock;
151 u8 version;
152
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530153 int reset_gpio;
154
155 int (*read_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
156 int bytes, void *dest, bool interface_reg);
157 int (*write_dev)(struct wcd9xxx *wcd9xxx, unsigned short reg,
Kuirong Wang906ac472012-07-09 12:54:44 -0700158 int bytes, void *src, bool interface_reg);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -0800159 int (*post_reset)(struct wcd9xxx *wcd9xxx);
160
161 void *ssr_priv;
162 bool slim_device_bootup;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530163
Kiran Kandi725f8492012-08-06 13:45:16 -0700164 u32 num_of_supplies;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530165 struct regulator_bulk_data *supplies;
166
167 enum wcd9xxx_pm_state pm_state;
168 struct mutex pm_lock;
169 /* pm_wq notifies change of pm_state */
170 wait_queue_head_t pm_wq;
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700171 struct pm_qos_request pm_qos_req;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530172 int wlock_holders;
Joonwoo Parkd7cf2e92012-03-19 19:38:23 -0700173
Venkat Sudhiree6c5002012-09-06 11:27:32 -0700174 u8 idbyte[4];
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700175
176 unsigned int irq_base;
177 unsigned int irq;
178 u8 irq_masks_cur[WCD9XXX_NUM_IRQ_REGS];
179 u8 irq_masks_cache[WCD9XXX_NUM_IRQ_REGS];
180 bool irq_level_high[WCD9XXX_MAX_NUM_IRQS];
181 int num_irqs;
Kuirong Wang906ac472012-07-09 12:54:44 -0700182 /* Slimbus or I2S port */
183 u32 num_rx_port;
184 u32 num_tx_port;
185 struct wcd9xxx_ch *rx_chs;
186 struct wcd9xxx_ch *tx_chs;
Venkat Sudhira50a3762012-11-26 12:12:15 -0800187 u32 mclk_rate;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530188};
189
190int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
191int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
192 u8 val);
193int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg);
194int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
195 u8 val);
196int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
197 int count, u8 *buf);
198int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
199 int count, u8 *buf);
200int wcd9xxx_irq_init(struct wcd9xxx *wcd9xxx);
201void wcd9xxx_irq_exit(struct wcd9xxx *wcd9xxx);
202int wcd9xxx_get_logical_addresses(u8 *pgd_la, u8 *inf_la);
Venkat Sudhira50a3762012-11-26 12:12:15 -0800203enum wcd9xxx_intf_status wcd9xxx_get_intf_type(void);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530204
Joonwoo Parkd7cf2e92012-03-19 19:38:23 -0700205bool wcd9xxx_lock_sleep(struct wcd9xxx *wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530206void wcd9xxx_unlock_sleep(struct wcd9xxx *wcd9xxx);
207enum wcd9xxx_pm_state wcd9xxx_pm_cmpxchg(struct wcd9xxx *wcd9xxx,
208 enum wcd9xxx_pm_state o,
209 enum wcd9xxx_pm_state n);
210
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700211int wcd9xxx_request_irq(struct wcd9xxx *wcd9xxx, int irq,
212 irq_handler_t handler, const char *name, void *data);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530213
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700214void wcd9xxx_free_irq(struct wcd9xxx *wcd9xxx, int irq, void *data);
215void wcd9xxx_enable_irq(struct wcd9xxx *wcd9xxx, int irq);
216void wcd9xxx_disable_irq(struct wcd9xxx *wcd9xxx, int irq);
217void wcd9xxx_disable_irq_sync(struct wcd9xxx *wcd9xxx, int irq);
Rohit Vaswani750bee12012-09-20 16:18:10 -0700218#if defined(CONFIG_WCD9310_CODEC) || \
219 defined(CONFIG_WCD9304_CODEC) || \
Banajit Goswami4d6d891b2012-12-12 23:59:07 -0800220 defined(CONFIG_WCD9320_CODEC) || \
221 defined(CONFIG_WCD9306_CODEC)
Joonwoo Parkf6574c72012-10-10 17:29:57 -0700222int __init wcd9xxx_irq_of_init(struct device_node *node,
223 struct device_node *parent);
Rohit Vaswani750bee12012-09-20 16:18:10 -0700224#else
225static inline int __init wcd9xxx_irq_of_init(struct device_node *node,
226 struct device_node *parent)
227{
228 return 0;
229}
Banajit Goswami4d6d891b2012-12-12 23:59:07 -0800230#endif /* CONFIG_OF */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530231#endif