1/* 2 * linux/arch/arm/mach-omap2/mcbsp.c 3 * 4 * Copyright (C) 2008 Instituto Nokia de Tecnologia 5 * Contact: Eduardo Valentin <eduardo.valentin@indt.org.br> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Multichannel mode not supported. 12 */ 13#include <linux/module.h> 14#include <linux/init.h> 15#include <linux/clk.h> 16#include <linux/err.h> 17#include <linux/io.h> 18#include <linux/platform_device.h> 19#include <linux/slab.h> 20 21#include <mach/irqs.h> 22#include <plat/dma.h> 23#include <plat/cpu.h> 24#include <plat/mcbsp.h> 25 26#include "mux.h" 27 28static void omap2_mcbsp2_mux_setup(void) 29{ 30 omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA); 31 omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA); 32 omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA); 33 omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA); 34 omap_mux_init_gpio(117, OMAP_PULL_ENA); 35 /* 36 * TODO: Need to add MUX settings for OMAP 2430 SDP 37 */ 38} 39 40static void omap2_mcbsp_request(unsigned int id) 41{ 42 if (cpu_is_omap2420() && (id == OMAP_MCBSP2)) 43 omap2_mcbsp2_mux_setup(); 44} 45 46static struct omap_mcbsp_ops omap2_mcbsp_ops = { 47 .request = omap2_mcbsp_request, 48}; 49 50#ifdef CONFIG_ARCH_OMAP2420 51static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = { 52 { 53 .phys_base = OMAP24XX_MCBSP1_BASE, 54 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, 55 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, 56 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 57 .tx_irq = INT_24XX_MCBSP1_IRQ_TX, 58 .ops = &omap2_mcbsp_ops, 59 }, 60 { 61 .phys_base = OMAP24XX_MCBSP2_BASE, 62 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, 63 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, 64 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 65 .tx_irq = INT_24XX_MCBSP2_IRQ_TX, 66 .ops = &omap2_mcbsp_ops, 67 }, 68}; 69#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata) 70#define OMAP2420_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) 71#else 72#define omap2420_mcbsp_pdata NULL 73#define OMAP2420_MCBSP_PDATA_SZ 0 74#define OMAP2420_MCBSP_REG_NUM 0 75#endif 76 77#ifdef CONFIG_ARCH_OMAP2430 78static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = { 79 { 80 .phys_base = OMAP24XX_MCBSP1_BASE, 81 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, 82 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, 83 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 84 .tx_irq = INT_24XX_MCBSP1_IRQ_TX, 85 .ops = &omap2_mcbsp_ops, 86 }, 87 { 88 .phys_base = OMAP24XX_MCBSP2_BASE, 89 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, 90 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, 91 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 92 .tx_irq = INT_24XX_MCBSP2_IRQ_TX, 93 .ops = &omap2_mcbsp_ops, 94 }, 95 { 96 .phys_base = OMAP2430_MCBSP3_BASE, 97 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, 98 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, 99 .rx_irq = INT_24XX_MCBSP3_IRQ_RX, 100 .tx_irq = INT_24XX_MCBSP3_IRQ_TX, 101 .ops = &omap2_mcbsp_ops, 102 }, 103 { 104 .phys_base = OMAP2430_MCBSP4_BASE, 105 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, 106 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, 107 .rx_irq = INT_24XX_MCBSP4_IRQ_RX, 108 .tx_irq = INT_24XX_MCBSP4_IRQ_TX, 109 .ops = &omap2_mcbsp_ops, 110 }, 111 { 112 .phys_base = OMAP2430_MCBSP5_BASE, 113 .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, 114 .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, 115 .rx_irq = INT_24XX_MCBSP5_IRQ_RX, 116 .tx_irq = INT_24XX_MCBSP5_IRQ_TX, 117 .ops = &omap2_mcbsp_ops, 118 }, 119}; 120#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata) 121#define OMAP2430_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) 122#else 123#define omap2430_mcbsp_pdata NULL 124#define OMAP2430_MCBSP_PDATA_SZ 0 125#define OMAP2430_MCBSP_REG_NUM 0 126#endif 127 128#ifdef CONFIG_ARCH_OMAP3 129static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = { 130 { 131 .phys_base = OMAP34XX_MCBSP1_BASE, 132 .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX, 133 .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX, 134 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 135 .tx_irq = INT_24XX_MCBSP1_IRQ_TX, 136 .ops = &omap2_mcbsp_ops, 137 .buffer_size = 0x80, /* The FIFO has 128 locations */ 138 }, 139 { 140 .phys_base = OMAP34XX_MCBSP2_BASE, 141 .phys_base_st = OMAP34XX_MCBSP2_ST_BASE, 142 .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX, 143 .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX, 144 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 145 .tx_irq = INT_24XX_MCBSP2_IRQ_TX, 146 .ops = &omap2_mcbsp_ops, 147 .buffer_size = 0x500, /* The FIFO has 1024 + 256 locations */ 148 }, 149 { 150 .phys_base = OMAP34XX_MCBSP3_BASE, 151 .phys_base_st = OMAP34XX_MCBSP3_ST_BASE, 152 .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX, 153 .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX, 154 .rx_irq = INT_24XX_MCBSP3_IRQ_RX, 155 .tx_irq = INT_24XX_MCBSP3_IRQ_TX, 156 .ops = &omap2_mcbsp_ops, 157 .buffer_size = 0x80, /* The FIFO has 128 locations */ 158 }, 159 { 160 .phys_base = OMAP34XX_MCBSP4_BASE, 161 .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX, 162 .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX, 163 .rx_irq = INT_24XX_MCBSP4_IRQ_RX, 164 .tx_irq = INT_24XX_MCBSP4_IRQ_TX, 165 .ops = &omap2_mcbsp_ops, 166 .buffer_size = 0x80, /* The FIFO has 128 locations */ 167 }, 168 { 169 .phys_base = OMAP34XX_MCBSP5_BASE, 170 .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX, 171 .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX, 172 .rx_irq = INT_24XX_MCBSP5_IRQ_RX, 173 .tx_irq = INT_24XX_MCBSP5_IRQ_TX, 174 .ops = &omap2_mcbsp_ops, 175 .buffer_size = 0x80, /* The FIFO has 128 locations */ 176 }, 177}; 178#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) 179#define OMAP34XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) 180#else 181#define omap34xx_mcbsp_pdata NULL 182#define OMAP34XX_MCBSP_PDATA_SZ 0 183#define OMAP34XX_MCBSP_REG_NUM 0 184#endif 185 186static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = { 187 { 188 .phys_base = OMAP44XX_MCBSP1_BASE, 189 .dma_rx_sync = OMAP44XX_DMA_MCBSP1_RX, 190 .dma_tx_sync = OMAP44XX_DMA_MCBSP1_TX, 191 .tx_irq = OMAP44XX_IRQ_MCBSP1, 192 .ops = &omap2_mcbsp_ops, 193 }, 194 { 195 .phys_base = OMAP44XX_MCBSP2_BASE, 196 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, 197 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, 198 .tx_irq = OMAP44XX_IRQ_MCBSP2, 199 .ops = &omap2_mcbsp_ops, 200 }, 201 { 202 .phys_base = OMAP44XX_MCBSP3_BASE, 203 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, 204 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, 205 .tx_irq = OMAP44XX_IRQ_MCBSP3, 206 .ops = &omap2_mcbsp_ops, 207 }, 208 { 209 .phys_base = OMAP44XX_MCBSP4_BASE, 210 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, 211 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, 212 .tx_irq = OMAP44XX_IRQ_MCBSP4, 213 .ops = &omap2_mcbsp_ops, 214 }, 215}; 216#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) 217#define OMAP44XX_MCBSP_REG_NUM (OMAP_MCBSP_REG_RCCR / sizeof(u32) + 1) 218 219static int __init omap2_mcbsp_init(void) 220{ 221 if (cpu_is_omap2420()) { 222 omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ; 223 omap_mcbsp_cache_size = OMAP2420_MCBSP_REG_NUM * sizeof(u16); 224 } else if (cpu_is_omap2430()) { 225 omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ; 226 omap_mcbsp_cache_size = OMAP2430_MCBSP_REG_NUM * sizeof(u32); 227 } else if (cpu_is_omap34xx()) { 228 omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ; 229 omap_mcbsp_cache_size = OMAP34XX_MCBSP_REG_NUM * sizeof(u32); 230 } else if (cpu_is_omap44xx()) { 231 omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ; 232 omap_mcbsp_cache_size = OMAP44XX_MCBSP_REG_NUM * sizeof(u32); 233 } 234 235 mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *), 236 GFP_KERNEL); 237 if (!mcbsp_ptr) 238 return -ENOMEM; 239 240 if (cpu_is_omap2420()) 241 omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata, 242 OMAP2420_MCBSP_PDATA_SZ); 243 if (cpu_is_omap2430()) 244 omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata, 245 OMAP2430_MCBSP_PDATA_SZ); 246 if (cpu_is_omap34xx()) 247 omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata, 248 OMAP34XX_MCBSP_PDATA_SZ); 249 if (cpu_is_omap44xx()) 250 omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata, 251 OMAP44XX_MCBSP_PDATA_SZ); 252 253 return omap_mcbsp_init(); 254} 255arch_initcall(omap2_mcbsp_init); 256