aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/mcbsp.c
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2011-02-24 04:46:53 -0500
committerTony Lindgren <tony@atomide.com>2011-02-24 16:03:12 -0500
commitf36d01d64f1caf0545214a5dc14096477f68cfbe (patch)
treebec0a1ca979d162b33b7a20f90280c9ac6a04585 /arch/arm/plat-omap/mcbsp.c
parent64bcbd33c7c70d0aea4e614212a2568321a0396b (diff)
OMAP: McBSP: use omap_device APIs to modify SYSCONFIG
McBSP2/3 in OMAP3 has sidetone feature which requires autoidle to be disabled before starting the sidetone. Also SYSCONFIG register has to be set with smart idle or no idle depending on the dma op mode (threshold or element sync). For doing these operations dynamically at runtime, omap_device APIs are used to modify SYSCONFIG register. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Cc: Paul Walmsley <paul@pwsan.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> [tony@atomide.com: updated to compile without omap_device idle calls] Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/plat-omap/mcbsp.c')
-rw-r--r--arch/arm/plat-omap/mcbsp.c59
1 files changed, 26 insertions, 33 deletions
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 62bd073b0f8f..67ec74ea2532 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,6 +27,7 @@
27 27
28#include <plat/dma.h> 28#include <plat/dma.h>
29#include <plat/mcbsp.h> 29#include <plat/mcbsp.h>
30#include <plat/omap_device.h>
30 31
31/* XXX These "sideways" includes are a sign that something is wrong */ 32/* XXX These "sideways" includes are a sign that something is wrong */
32#include "../mach-omap2/cm2xxx_3xxx.h" 33#include "../mach-omap2/cm2xxx_3xxx.h"
@@ -228,9 +229,19 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
228EXPORT_SYMBOL(omap_mcbsp_config); 229EXPORT_SYMBOL(omap_mcbsp_config);
229 230
230#ifdef CONFIG_ARCH_OMAP3 231#ifdef CONFIG_ARCH_OMAP3
232static struct omap_device *find_omap_device_by_dev(struct device *dev)
233{
234 struct platform_device *pdev = container_of(dev,
235 struct platform_device, dev);
236 return container_of(pdev, struct omap_device, pdev);
237}
238
231static void omap_st_on(struct omap_mcbsp *mcbsp) 239static void omap_st_on(struct omap_mcbsp *mcbsp)
232{ 240{
233 unsigned int w; 241 unsigned int w;
242 struct omap_device *od;
243
244 od = find_omap_device_by_dev(mcbsp->dev);
234 245
235 /* 246 /*
236 * Sidetone uses McBSP ICLK - which must not idle when sidetones 247 * Sidetone uses McBSP ICLK - which must not idle when sidetones
@@ -244,9 +255,6 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
244 w = MCBSP_READ(mcbsp, SSELCR); 255 w = MCBSP_READ(mcbsp, SSELCR);
245 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN); 256 MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN);
246 257
247 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
248 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
249
250 /* Enable Sidetone from Sidetone Core */ 258 /* Enable Sidetone from Sidetone Core */
251 w = MCBSP_ST_READ(mcbsp, SSELCR); 259 w = MCBSP_ST_READ(mcbsp, SSELCR);
252 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN); 260 MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN);
@@ -255,13 +263,13 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
255static void omap_st_off(struct omap_mcbsp *mcbsp) 263static void omap_st_off(struct omap_mcbsp *mcbsp)
256{ 264{
257 unsigned int w; 265 unsigned int w;
266 struct omap_device *od;
267
268 od = find_omap_device_by_dev(mcbsp->dev);
258 269
259 w = MCBSP_ST_READ(mcbsp, SSELCR); 270 w = MCBSP_ST_READ(mcbsp, SSELCR);
260 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN)); 271 MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
261 272
262 w = MCBSP_ST_READ(mcbsp, SYSCONFIG);
263 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w | ST_AUTOIDLE);
264
265 w = MCBSP_READ(mcbsp, SSELCR); 273 w = MCBSP_READ(mcbsp, SSELCR);
266 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN)); 274 MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
267 275
@@ -273,9 +281,9 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
273static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir) 281static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
274{ 282{
275 u16 val, i; 283 u16 val, i;
284 struct omap_device *od;
276 285
277 val = MCBSP_ST_READ(mcbsp, SYSCONFIG); 286 od = find_omap_device_by_dev(mcbsp->dev);
278 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, val & ~(ST_AUTOIDLE));
279 287
280 val = MCBSP_ST_READ(mcbsp, SSELCR); 288 val = MCBSP_ST_READ(mcbsp, SSELCR);
281 289
@@ -303,9 +311,9 @@ static void omap_st_chgain(struct omap_mcbsp *mcbsp)
303{ 311{
304 u16 w; 312 u16 w;
305 struct omap_mcbsp_st_data *st_data = mcbsp->st_data; 313 struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
314 struct omap_device *od;
306 315
307 w = MCBSP_ST_READ(mcbsp, SYSCONFIG); 316 od = find_omap_device_by_dev(mcbsp->dev);
308 MCBSP_ST_WRITE(mcbsp, SYSCONFIG, w & ~(ST_AUTOIDLE));
309 317
310 w = MCBSP_ST_READ(mcbsp, SSELCR); 318 w = MCBSP_ST_READ(mcbsp, SSELCR);
311 319
@@ -648,48 +656,33 @@ EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
648 656
649static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) 657static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
650{ 658{
659 struct omap_device *od;
660
661 od = find_omap_device_by_dev(mcbsp->dev);
651 /* 662 /*
652 * Enable wakup behavior, smart idle and all wakeups 663 * Enable wakup behavior, smart idle and all wakeups
653 * REVISIT: some wakeups may be unnecessary 664 * REVISIT: some wakeups may be unnecessary
654 */ 665 */
655 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 666 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
656 u16 syscon; 667 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
657
658 syscon = MCBSP_READ(mcbsp, SYSCON);
659 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
660
661 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
662 syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
663 CLOCKACTIVITY(0x02));
664 MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
665 } else {
666 syscon |= SIDLEMODE(0x01);
667 }
668
669 MCBSP_WRITE(mcbsp, SYSCON, syscon);
670 } 668 }
671} 669}
672 670
673static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) 671static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
674{ 672{
673 struct omap_device *od;
674
675 od = find_omap_device_by_dev(mcbsp->dev);
676
675 /* 677 /*
676 * Disable wakup behavior, smart idle and all wakeups 678 * Disable wakup behavior, smart idle and all wakeups
677 */ 679 */
678 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 680 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
679 u16 syscon;
680
681 syscon = MCBSP_READ(mcbsp, SYSCON);
682 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
683 /* 681 /*
684 * HW bug workaround - If no_idle mode is taken, we need to 682 * HW bug workaround - If no_idle mode is taken, we need to
685 * go to smart_idle before going to always_idle, or the 683 * go to smart_idle before going to always_idle, or the
686 * device will not hit retention anymore. 684 * device will not hit retention anymore.
687 */ 685 */
688 syscon |= SIDLEMODE(0x02);
689 MCBSP_WRITE(mcbsp, SYSCON, syscon);
690
691 syscon &= ~(SIDLEMODE(0x03));
692 MCBSP_WRITE(mcbsp, SYSCON, syscon);
693 686
694 MCBSP_WRITE(mcbsp, WAKEUPEN, 0); 687 MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
695 } 688 }