178673bc8SEduardo Valentin /* 278673bc8SEduardo Valentin * linux/arch/arm/mach-omap2/mcbsp.c 378673bc8SEduardo Valentin * 478673bc8SEduardo Valentin * Copyright (C) 2008 Instituto Nokia de Tecnologia 578673bc8SEduardo Valentin * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br> 678673bc8SEduardo Valentin * 778673bc8SEduardo Valentin * This program is free software; you can redistribute it and/or modify 878673bc8SEduardo Valentin * it under the terms of the GNU General Public License version 2 as 978673bc8SEduardo Valentin * published by the Free Software Foundation. 1078673bc8SEduardo Valentin * 1178673bc8SEduardo Valentin * Multichannel mode not supported. 1278673bc8SEduardo Valentin */ 1378673bc8SEduardo Valentin #include <linux/module.h> 1478673bc8SEduardo Valentin #include <linux/init.h> 1578673bc8SEduardo Valentin #include <linux/clk.h> 1678673bc8SEduardo Valentin #include <linux/err.h> 1778673bc8SEduardo Valentin #include <linux/io.h> 18e586e955SPeter Ujfalusi #include <linux/of.h> 1978673bc8SEduardo Valentin #include <linux/platform_device.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 212203747cSArnd Bergmann #include <linux/platform_data/asoc-ti-mcbsp.h> 2225c7d49eSTony Lindgren #include <linux/pm_runtime.h> 2378673bc8SEduardo Valentin 2445c3eb7dSTony Lindgren #include <linux/omap-dma.h> 2525c7d49eSTony Lindgren 26*b76c8b19STony Lindgren #include "soc.h" 2725c7d49eSTony Lindgren #include "omap_device.h" 284814ced5SPaul Walmsley 291743d14fSJarkko Nikula /* 301743d14fSJarkko Nikula * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle. 311743d14fSJarkko Nikula * Sidetone needs non-gated ICLK and sidetone autoidle is broken. 321743d14fSJarkko Nikula */ 33d9a16f9aSPaul Walmsley #include "cm3xxx.h" 341743d14fSJarkko Nikula #include "cm-regbits-34xx.h" 351743d14fSJarkko Nikula 361743d14fSJarkko Nikula static int omap3_enable_st_clock(unsigned int id, bool enable) 371743d14fSJarkko Nikula { 381743d14fSJarkko Nikula unsigned int w; 391743d14fSJarkko Nikula 401743d14fSJarkko Nikula /* 411743d14fSJarkko Nikula * Sidetone uses McBSP ICLK - which must not idle when sidetones 421743d14fSJarkko Nikula * are enabled or sidetones start sounding ugly. 431743d14fSJarkko Nikula */ 441743d14fSJarkko Nikula w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE); 451743d14fSJarkko Nikula if (enable) 461743d14fSJarkko Nikula w &= ~(1 << (id - 2)); 471743d14fSJarkko Nikula else 481743d14fSJarkko Nikula w |= 1 << (id - 2); 491743d14fSJarkko Nikula omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE); 501743d14fSJarkko Nikula 511743d14fSJarkko Nikula return 0; 521743d14fSJarkko Nikula } 531743d14fSJarkko Nikula 549cf793f9SKevin Hilman static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) 5578673bc8SEduardo Valentin { 5664bcbd33SKishon Vijay Abraham I int id, count = 1; 5764bcbd33SKishon Vijay Abraham I char *name = "omap-mcbsp"; 5864bcbd33SKishon Vijay Abraham I struct omap_hwmod *oh_device[2]; 5964bcbd33SKishon Vijay Abraham I struct omap_mcbsp_platform_data *pdata = NULL; 603528c58eSKevin Hilman struct platform_device *pdev; 6178673bc8SEduardo Valentin 6264bcbd33SKishon Vijay Abraham I sscanf(oh->name, "mcbsp%d", &id); 6364bcbd33SKishon Vijay Abraham I 6464bcbd33SKishon Vijay Abraham I pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); 6564bcbd33SKishon Vijay Abraham I if (!pdata) { 6664bcbd33SKishon Vijay Abraham I pr_err("%s: No memory for mcbsp\n", __func__); 6764bcbd33SKishon Vijay Abraham I return -ENOMEM; 6864bcbd33SKishon Vijay Abraham I } 6964bcbd33SKishon Vijay Abraham I 70cdc71514SJarkko Nikula pdata->reg_step = 4; 7188408230SJarkko Nikula if (oh->class->rev < MCBSP_CONFIG_TYPE2) { 72cdc71514SJarkko Nikula pdata->reg_size = 2; 7388408230SJarkko Nikula } else { 74cdc71514SJarkko Nikula pdata->reg_size = 4; 7588408230SJarkko Nikula pdata->has_ccr = true; 7688408230SJarkko Nikula } 7740c0764bSPeter Ujfalusi 78cafebc4aSPeter Ujfalusi if (oh->class->rev == MCBSP_CONFIG_TYPE2) { 79cafebc4aSPeter Ujfalusi /* The FIFO has 128 locations */ 80cafebc4aSPeter Ujfalusi pdata->buffer_size = 0x80; 81cafebc4aSPeter Ujfalusi } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { 8264bcbd33SKishon Vijay Abraham I if (id == 2) 8364bcbd33SKishon Vijay Abraham I /* The FIFO has 1024 + 256 locations */ 8464bcbd33SKishon Vijay Abraham I pdata->buffer_size = 0x500; 8564bcbd33SKishon Vijay Abraham I else 8664bcbd33SKishon Vijay Abraham I /* The FIFO has 128 locations */ 8764bcbd33SKishon Vijay Abraham I pdata->buffer_size = 0x80; 88da76250eSPeter Ujfalusi } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) { 89da76250eSPeter Ujfalusi /* The FIFO has 128 locations for all instances */ 90da76250eSPeter Ujfalusi pdata->buffer_size = 0x80; 9164bcbd33SKishon Vijay Abraham I } 9264bcbd33SKishon Vijay Abraham I 931a645884SJarkko Nikula if (oh->class->rev >= MCBSP_CONFIG_TYPE3) 941a645884SJarkko Nikula pdata->has_wakeup = true; 951a645884SJarkko Nikula 9664bcbd33SKishon Vijay Abraham I oh_device[0] = oh; 9764bcbd33SKishon Vijay Abraham I 9864bcbd33SKishon Vijay Abraham I if (oh->dev_attr) { 9964bcbd33SKishon Vijay Abraham I oh_device[1] = omap_hwmod_lookup(( 10064bcbd33SKishon Vijay Abraham I (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); 1011743d14fSJarkko Nikula pdata->enable_st_clock = omap3_enable_st_clock; 10264bcbd33SKishon Vijay Abraham I count++; 10364bcbd33SKishon Vijay Abraham I } 1043528c58eSKevin Hilman pdev = omap_device_build_ss(name, id, oh_device, count, pdata, 105f718e2c0SBenoit Cousson sizeof(*pdata), NULL, 0, false); 10664bcbd33SKishon Vijay Abraham I kfree(pdata); 1073528c58eSKevin Hilman if (IS_ERR(pdev)) { 10825985edcSLucas De Marchi pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, 10964bcbd33SKishon Vijay Abraham I name, oh->name); 1103528c58eSKevin Hilman return PTR_ERR(pdev); 11164bcbd33SKishon Vijay Abraham I } 11264bcbd33SKishon Vijay Abraham I return 0; 11364bcbd33SKishon Vijay Abraham I } 114a5b92cc3SSyed Rafiuddin 115b4b58f58SChandra Shekhar static int __init omap2_mcbsp_init(void) 11678673bc8SEduardo Valentin { 117e586e955SPeter Ujfalusi if (!of_have_populated_dt()) 11864bcbd33SKishon Vijay Abraham I omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); 119b4b58f58SChandra Shekhar 1200210dc4eSPeter Ujfalusi return 0; 12178673bc8SEduardo Valentin } 122*b76c8b19STony Lindgren omap_arch_initcall(omap2_mcbsp_init); 123