aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorMisael Lopez Cruz <misael.lopez@ti.com>2011-04-27 03:14:07 -0400
committerPeter Ujfalusi <peter.ujfalusi@ti.com>2011-07-04 12:34:37 -0400
commitf19b2823f82499c60ec15d5fe8783193d77e3043 (patch)
tree75148aed2558ec27ca87cf94e7ec3f398cd77e96 /include/linux
parent4ae6df5e1018796ce260be59b2c603bd0f9faa94 (diff)
mfd: twl6040: Add initial support
TWL6040 IC provides analog high-end audio codec functions for handset applications. It contains several audio analog inputs and outputs as well as vibrator support. It's connected to the host processor via PDM interface for audio data communication. The audio modules are controlled by internal registers that can be accessed by I2C and PDM interface. TWL6040 MFD will be registered as a child of TWL-CORE, and will have two children of its own: twl6040-codec and twl6040-vibra. This driver is based on TWL4030 and WM8350 MFD drivers. Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/i2c/twl.h1
-rw-r--r--include/linux/mfd/twl6040.h255
2 files changed, 256 insertions, 0 deletions
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index e0aba2b92fa1..ea5baa269226 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -679,6 +679,7 @@ struct twl4030_audio_data {
679 /* twl6040 */ 679 /* twl6040 */
680 int audpwron_gpio; /* audio power-on gpio */ 680 int audpwron_gpio; /* audio power-on gpio */
681 int naudint_irq; /* audio interrupt */ 681 int naudint_irq; /* audio interrupt */
682 unsigned int irq_base;
682}; 683};
683 684
684struct twl4030_platform_data { 685struct twl4030_platform_data {
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
new file mode 100644
index 000000000000..c3c1de53dcfe
--- /dev/null
+++ b/include/linux/mfd/twl6040.h
@@ -0,0 +1,255 @@
1/*
2 * MFD driver for twl6040
3 *
4 * Authors: Jorge Eduardo Candelaria <jorge.candelaria@ti.com>
5 * Misael Lopez Cruz <misael.lopez@ti.com>
6 *
7 * Copyright: (C) 2011 Texas Instruments, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#ifndef __TWL6040_CODEC_H__
26#define __TWL6040_CODEC_H__
27
28#include <linux/interrupt.h>
29#include <linux/mfd/core.h>
30
31#define TWL6040_REG_ASICID 0x01
32#define TWL6040_REG_ASICREV 0x02
33#define TWL6040_REG_INTID 0x03
34#define TWL6040_REG_INTMR 0x04
35#define TWL6040_REG_NCPCTL 0x05
36#define TWL6040_REG_LDOCTL 0x06
37#define TWL6040_REG_HPPLLCTL 0x07
38#define TWL6040_REG_LPPLLCTL 0x08
39#define TWL6040_REG_LPPLLDIV 0x09
40#define TWL6040_REG_AMICBCTL 0x0A
41#define TWL6040_REG_DMICBCTL 0x0B
42#define TWL6040_REG_MICLCTL 0x0C
43#define TWL6040_REG_MICRCTL 0x0D
44#define TWL6040_REG_MICGAIN 0x0E
45#define TWL6040_REG_LINEGAIN 0x0F
46#define TWL6040_REG_HSLCTL 0x10
47#define TWL6040_REG_HSRCTL 0x11
48#define TWL6040_REG_HSGAIN 0x12
49#define TWL6040_REG_EARCTL 0x13
50#define TWL6040_REG_HFLCTL 0x14
51#define TWL6040_REG_HFLGAIN 0x15
52#define TWL6040_REG_HFRCTL 0x16
53#define TWL6040_REG_HFRGAIN 0x17
54#define TWL6040_REG_VIBCTLL 0x18
55#define TWL6040_REG_VIBDATL 0x19
56#define TWL6040_REG_VIBCTLR 0x1A
57#define TWL6040_REG_VIBDATR 0x1B
58#define TWL6040_REG_HKCTL1 0x1C
59#define TWL6040_REG_HKCTL2 0x1D
60#define TWL6040_REG_GPOCTL 0x1E
61#define TWL6040_REG_ALB 0x1F
62#define TWL6040_REG_DLB 0x20
63#define TWL6040_REG_TRIM1 0x28
64#define TWL6040_REG_TRIM2 0x29
65#define TWL6040_REG_TRIM3 0x2A
66#define TWL6040_REG_HSOTRIM 0x2B
67#define TWL6040_REG_HFOTRIM 0x2C
68#define TWL6040_REG_ACCCTL 0x2D
69#define TWL6040_REG_STATUS 0x2E
70
71#define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1)
72
73#define TWL6040_VIOREGNUM 18
74#define TWL6040_VDDREGNUM 21
75
76/* INTID (0x03) fields */
77
78#define TWL6040_THINT 0x01
79#define TWL6040_PLUGINT 0x02
80#define TWL6040_UNPLUGINT 0x04
81#define TWL6040_HOOKINT 0x08
82#define TWL6040_HFINT 0x10
83#define TWL6040_VIBINT 0x20
84#define TWL6040_READYINT 0x40
85
86/* INTMR (0x04) fields */
87
88#define TWL6040_THMSK 0x01
89#define TWL6040_PLUGMSK 0x02
90#define TWL6040_HOOKMSK 0x08
91#define TWL6040_HFMSK 0x10
92#define TWL6040_VIBMSK 0x20
93#define TWL6040_READYMSK 0x40
94#define TWL6040_ALLINT_MSK 0x7B
95
96/* NCPCTL (0x05) fields */
97
98#define TWL6040_NCPENA 0x01
99#define TWL6040_NCPOPEN 0x40
100
101/* LDOCTL (0x06) fields */
102
103#define TWL6040_LSLDOENA 0x01
104#define TWL6040_HSLDOENA 0x04
105#define TWL6040_REFENA 0x40
106#define TWL6040_OSCENA 0x80
107
108/* HPPLLCTL (0x07) fields */
109
110#define TWL6040_HPLLENA 0x01
111#define TWL6040_HPLLRST 0x02
112#define TWL6040_HPLLBP 0x04
113#define TWL6040_HPLLSQRENA 0x08
114#define TWL6040_MCLK_12000KHZ (0 << 5)
115#define TWL6040_MCLK_19200KHZ (1 << 5)
116#define TWL6040_MCLK_26000KHZ (2 << 5)
117#define TWL6040_MCLK_38400KHZ (3 << 5)
118#define TWL6040_MCLK_MSK 0x60
119
120/* LPPLLCTL (0x08) fields */
121
122#define TWL6040_LPLLENA 0x01
123#define TWL6040_LPLLRST 0x02
124#define TWL6040_LPLLSEL 0x04
125#define TWL6040_LPLLFIN 0x08
126#define TWL6040_HPLLSEL 0x10
127
128/* HSLCTL (0x10) fields */
129
130#define TWL6040_HSDACMODEL 0x02
131#define TWL6040_HSDRVMODEL 0x08
132
133/* HSRCTL (0x11) fields */
134
135#define TWL6040_HSDACMODER 0x02
136#define TWL6040_HSDRVMODER 0x08
137
138/* VIBCTLL (0x18) fields */
139
140#define TWL6040_VIBENAL 0x01
141#define TWL6040_VIBCTRLL 0x04
142#define TWL6040_VIBCTRLLP 0x08
143#define TWL6040_VIBCTRLLN 0x10
144
145/* VIBDATL (0x19) fields */
146
147#define TWL6040_VIBDAT_MAX 0x64
148
149/* VIBCTLR (0x1A) fields */
150
151#define TWL6040_VIBENAR 0x01
152#define TWL6040_VIBCTRLR 0x04
153#define TWL6040_VIBCTRLRP 0x08
154#define TWL6040_VIBCTRLRN 0x10
155
156/* GPOCTL (0x1E) fields */
157
158#define TWL6040_GPO1 0x01
159#define TWL6040_GPO2 0x02
160#define TWL6040_GPO3 0x03
161
162/* ACCCTL (0x2D) fields */
163
164#define TWL6040_I2CSEL 0x01
165#define TWL6040_RESETSPLIT 0x04
166#define TWL6040_INTCLRMODE 0x08
167
168#define TWL6040_SYSCLK_SEL_LPPLL 1
169#define TWL6040_SYSCLK_SEL_HPPLL 2
170
171/* STATUS (0x2E) fields */
172
173#define TWL6040_PLUGCOMP 0x02
174#define TWL6040_VIBLOCDET 0x10
175#define TWL6040_VIBROCDET 0x20
176#define TWL6040_TSHUTDET 0x40
177
178#define TWL6040_CELLS 2
179
180#define TWL6040_REV_ES1_0 0x00
181#define TWL6040_REV_ES1_1 0x01
182#define TWL6040_REV_ES1_2 0x02
183
184#define TWL6040_IRQ_TH 0
185#define TWL6040_IRQ_PLUG 1
186#define TWL6040_IRQ_HOOK 2
187#define TWL6040_IRQ_HF 3
188#define TWL6040_IRQ_VIB 4
189#define TWL6040_IRQ_READY 5
190
191enum twl6040_pll_id {
192 TWL6040_NOPLL_ID,
193 TWL6040_LPPLL_ID,
194 TWL6040_HPPLL_ID,
195};
196
197struct twl6040 {
198 struct device *dev;
199 struct mutex mutex;
200 struct mutex io_mutex;
201 struct mutex irq_mutex;
202 struct mfd_cell cells[TWL6040_CELLS];
203 struct completion ready;
204
205 int audpwron;
206 int power_count;
207 int rev;
208
209 enum twl6040_pll_id pll;
210 unsigned int sysclk;
211
212 unsigned int irq;
213 unsigned int irq_base;
214 u8 irq_masks_cur;
215 u8 irq_masks_cache;
216};
217
218static inline int twl6040_request_irq(struct twl6040 *twl6040, int irq,
219 irq_handler_t handler,
220 unsigned long irqflags,
221 const char *name,
222 void *data)
223{
224 if (!twl6040->irq_base)
225 return -EINVAL;
226
227 return request_threaded_irq(twl6040->irq_base + irq, NULL, handler,
228 irqflags, name, data);
229}
230
231static inline void twl6040_free_irq(struct twl6040 *twl6040, int irq,
232 void *data)
233{
234 if (!twl6040->irq_base)
235 return;
236
237 free_irq(twl6040->irq_base + irq, data);
238}
239
240int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg);
241int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg,
242 u8 val);
243int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg,
244 u8 mask);
245int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg,
246 u8 mask);
247int twl6040_power(struct twl6040 *twl6040, int on);
248int twl6040_set_pll(struct twl6040 *twl6040, enum twl6040_pll_id id,
249 unsigned int freq_in, unsigned int freq_out);
250enum twl6040_pll_id twl6040_get_pll(struct twl6040 *twl6040);
251unsigned int twl6040_get_sysclk(struct twl6040 *twl6040);
252int twl6040_irq_init(struct twl6040 *twl6040);
253void twl6040_irq_exit(struct twl6040 *twl6040);
254
255#endif /* End of __TWL6040_CODEC_H__ */