2 * linux/drivers/mfd/mcp-sa11x0.c
4 * Copyright (C) 2001-2005 Russell King
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License.
10 * SA11x0 MCP (Multimedia Communications Port) driver.
12 * MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/errno.h>
17 #include <linux/kernel.h>
18 #include <linux/delay.h>
19 #include <linux/spinlock.h>
20 #include <linux/platform_device.h>
21 #include <linux/mfd/mcp.h>
25 #include <mach/hardware.h>
26 #include <asm/mach-types.h>
27 #include <asm/system.h>
30 /* Register offsets */
41 unsigned char *mccr0_base
;
42 unsigned char *mccr1_base
;
45 #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
48 mcp_sa11x0_set_telecom_divisor(struct mcp
*mcp
, unsigned int divisor
)
50 struct mcp_sa11x0
*priv
= priv(mcp
);
54 priv
->mccr0
&= ~0x00007f00;
55 priv
->mccr0
|= divisor
<< 8;
56 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
60 mcp_sa11x0_set_audio_divisor(struct mcp
*mcp
, unsigned int divisor
)
62 struct mcp_sa11x0
*priv
= priv(mcp
);
66 priv
->mccr0
&= ~0x0000007f;
67 priv
->mccr0
|= divisor
;
68 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
72 * Write data to the device. The bit should be set after 3 subframe
73 * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
74 * We really should try doing something more productive while we
78 mcp_sa11x0_write(struct mcp
*mcp
, unsigned int reg
, unsigned int val
)
83 struct mcp_sa11x0
*priv
= priv(mcp
);
85 mcpreg
= reg
<< 17 | MCDR2_Wr
| (val
& 0xffff);
86 __raw_writel(mcpreg
, priv
->mccr0_base
+ MCDR2
);
88 for (i
= 0; i
< 2; i
++) {
89 udelay(mcp
->rw_timeout
);
90 mcpreg
= __raw_readl(priv
->mccr0_base
+ MCSR
);
91 if (mcpreg
& MCSR_CWC
) {
98 printk(KERN_WARNING
"mcp: write timed out\n");
102 * Read data from the device. The bit should be set after 3 subframe
103 * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
104 * We really should try doing something more productive while we
108 mcp_sa11x0_read(struct mcp
*mcp
, unsigned int reg
)
113 struct mcp_sa11x0
*priv
= priv(mcp
);
115 mcpreg
= reg
<< 17 | MCDR2_Rd
;
116 __raw_writel(mcpreg
, priv
->mccr0_base
+ MCDR2
);
118 for (i
= 0; i
< 2; i
++) {
119 udelay(mcp
->rw_timeout
);
120 mcpreg
= __raw_readl(priv
->mccr0_base
+ MCSR
);
121 if (mcpreg
& MCSR_CRC
) {
122 ret
= __raw_readl(priv
->mccr0_base
+ MCDR2
)
129 printk(KERN_WARNING
"mcp: read timed out\n");
134 static void mcp_sa11x0_enable(struct mcp
*mcp
)
136 struct mcp_sa11x0
*priv
= priv(mcp
);
138 __raw_writel(-1, priv
->mccr0_base
+ MCSR
);
139 priv
->mccr0
|= MCCR0_MCE
;
140 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
143 static void mcp_sa11x0_disable(struct mcp
*mcp
)
145 struct mcp_sa11x0
*priv
= priv(mcp
);
147 priv
->mccr0
&= ~MCCR0_MCE
;
148 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
154 static struct mcp_ops mcp_sa11x0
= {
155 .set_telecom_divisor
= mcp_sa11x0_set_telecom_divisor
,
156 .set_audio_divisor
= mcp_sa11x0_set_audio_divisor
,
157 .reg_write
= mcp_sa11x0_write
,
158 .reg_read
= mcp_sa11x0_read
,
159 .enable
= mcp_sa11x0_enable
,
160 .disable
= mcp_sa11x0_disable
,
163 static int mcp_sa11x0_probe(struct platform_device
*pdev
)
165 struct mcp_plat_data
*data
= pdev
->dev
.platform_data
;
168 struct mcp_sa11x0
*priv
;
169 struct resource
*res_mem0
, *res_mem1
;
178 res_mem0
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
181 size0
= res_mem0
->end
- res_mem0
->start
+ 1;
183 res_mem1
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
186 size1
= res_mem1
->end
- res_mem1
->start
+ 1;
188 if (!request_mem_region(res_mem0
->start
, size0
, "sa11x0-mcp"))
191 if (!request_mem_region(res_mem1
->start
, size1
, "sa11x0-mcp")) {
196 mcp
= mcp_host_alloc(&pdev
->dev
, sizeof(struct mcp_sa11x0
));
204 mcp
->owner
= THIS_MODULE
;
205 mcp
->ops
= &mcp_sa11x0
;
206 mcp
->sclk_rate
= data
->sclk_rate
;
207 mcp
->dma_audio_rd
= DDAR_DevAdd(res_mem0
->start
+ MCDR0
)
208 + DDAR_DevRd
+ DDAR_Brst4
+ DDAR_8BitDev
;
209 mcp
->dma_audio_wr
= DDAR_DevAdd(res_mem0
->start
+ MCDR0
)
210 + DDAR_DevWr
+ DDAR_Brst4
+ DDAR_8BitDev
;
211 mcp
->dma_telco_rd
= DDAR_DevAdd(res_mem0
->start
+ MCDR1
)
212 + DDAR_DevRd
+ DDAR_Brst4
+ DDAR_8BitDev
;
213 mcp
->dma_telco_wr
= DDAR_DevAdd(res_mem0
->start
+ MCDR1
)
214 + DDAR_DevWr
+ DDAR_Brst4
+ DDAR_8BitDev
;
215 mcp
->codec
= data
->codec
;
217 platform_set_drvdata(pdev
, mcp
);
220 * Initialise device. Note that we initially
221 * set the sampling rate to minimum.
223 priv
->mccr0_base
= ioremap(res_mem0
->start
, size0
);
224 priv
->mccr1_base
= ioremap(res_mem1
->start
, size1
);
226 __raw_writel(-1, priv
->mccr0_base
+ MCSR
);
227 priv
->mccr1
= data
->mccr1
;
228 priv
->mccr0
= data
->mccr0
| 0x7f7f;
229 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
230 __raw_writel(priv
->mccr1
, priv
->mccr1_base
+ MCCR1
);
233 * Calculate the read/write timeout (us) from the bit clock
234 * rate. This is the period for 3 64-bit frames. Always
235 * round this time up.
237 mcp
->rw_timeout
= (64 * 3 * 1000000 + mcp
->sclk_rate
- 1) /
240 ret
= mcp_host_register(mcp
, data
->codec_pdata
);
245 release_mem_region(res_mem1
->start
, size1
);
247 release_mem_region(res_mem0
->start
, size0
);
248 platform_set_drvdata(pdev
, NULL
);
254 static int mcp_sa11x0_remove(struct platform_device
*pdev
)
256 struct mcp
*mcp
= platform_get_drvdata(pdev
);
257 struct mcp_sa11x0
*priv
= priv(mcp
);
258 struct resource
*res_mem
;
261 platform_set_drvdata(pdev
, NULL
);
262 mcp_host_unregister(mcp
);
264 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
266 size
= res_mem
->end
- res_mem
->start
+ 1;
267 release_mem_region(res_mem
->start
, size
);
269 res_mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
271 size
= res_mem
->end
- res_mem
->start
+ 1;
272 release_mem_region(res_mem
->start
, size
);
274 iounmap(priv
->mccr0_base
);
275 iounmap(priv
->mccr1_base
);
279 static int mcp_sa11x0_suspend(struct platform_device
*dev
, pm_message_t state
)
281 struct mcp
*mcp
= platform_get_drvdata(dev
);
282 struct mcp_sa11x0
*priv
= priv(mcp
);
285 mccr0
= priv
->mccr0
& ~MCCR0_MCE
;
286 __raw_writel(mccr0
, priv
->mccr0_base
+ MCCR0
);
291 static int mcp_sa11x0_resume(struct platform_device
*dev
)
293 struct mcp
*mcp
= platform_get_drvdata(dev
);
294 struct mcp_sa11x0
*priv
= priv(mcp
);
296 __raw_writel(priv
->mccr0
, priv
->mccr0_base
+ MCCR0
);
297 __raw_writel(priv
->mccr1
, priv
->mccr1_base
+ MCCR1
);
303 * The driver for the SA11x0 MCP port.
305 MODULE_ALIAS("platform:sa11x0-mcp");
307 static struct platform_driver mcp_sa11x0_driver
= {
308 .probe
= mcp_sa11x0_probe
,
309 .remove
= mcp_sa11x0_remove
,
310 .suspend
= mcp_sa11x0_suspend
,
311 .resume
= mcp_sa11x0_resume
,
313 .name
= "sa11x0-mcp",
314 .owner
= THIS_MODULE
,
319 * This needs re-working
321 module_platform_driver(mcp_sa11x0_driver
);
323 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
324 MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
325 MODULE_LICENSE("GPL");