aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-10-08 13:40:19 -0400
committerPaul Walmsley <paul@pwsan.com>2010-10-08 13:40:19 -0400
commitd13586574d373ef40acd4725c9a269daa355e412 (patch)
tree93e4a7c46fa0c2e1cccea572ef995dbde5c1fd19 /arch/arm
parentcf4c87abe238ec17cd0255b4e21abd949d7f811e (diff)
OMAP: McBSP: implement functional clock switching via clock framework
Previously the OMAP McBSP ASoC driver implemented CLKS switching by using omap_ctrl_{read,write}l() directly. This is against policy; the OMAP System Control Module functions are not intended to be exported to drivers. These symbols are no longer exported, so as a result, the OMAP McBSP ASoC driver does not build as a module. Resolve the CLKS clock changing portion of this problem by creating a clock parent changing function that lives in arch/arm/mach-omap2/mcbsp.c, and modify the ASoC driver to use it. Due to the unfortunate way that McBSP support is implemented in ASoC and the OMAP tree, this symbol must be exported for use by sound/soc/omap/omap-mcbsp.c. Going forward, the McBSP device driver should be moved from arch/arm/*omap* into drivers/ or sound/soc/* and the CPU DAI driver should be implemented as a platform_driver as many other ASoC CPU DAI drivers are. These two steps should resolve many of the layering problems, which will rapidly reappear during a McBSP hwmod/PM runtime conversions. Signed-off-by: Paul Walmsley <paul@pwsan.com> Acked-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Peter Ujfalusi <peter.ujfalusi@nokia.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-omap2/mcbsp.c51
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h11
-rw-r--r--arch/arm/plat-omap/mcbsp.c3
3 files changed, 62 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 4c9c999dfa4a..51abcedfde83 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -52,6 +52,54 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux)
52} 52}
53EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src); 53EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
54 54
55/* McBSP CLKS source switching function */
56
57int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
58{
59 struct omap_mcbsp *mcbsp;
60 struct clk *fck_src;
61 char *fck_src_name;
62 int r;
63
64 if (!omap_mcbsp_check_valid_id(id)) {
65 pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
66 return -EINVAL;
67 }
68 mcbsp = id_to_mcbsp_ptr(id);
69
70 if (fck_src_id == MCBSP_CLKS_PAD_SRC)
71 fck_src_name = "pad_fck";
72 else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
73 fck_src_name = "prcm_fck";
74 else
75 return -EINVAL;
76
77 fck_src = clk_get(mcbsp->dev, fck_src_name);
78 if (IS_ERR_OR_NULL(fck_src)) {
79 pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
80 fck_src_name);
81 return -EINVAL;
82 }
83
84 clk_disable(mcbsp->fclk);
85
86 r = clk_set_parent(mcbsp->fclk, fck_src);
87 if (IS_ERR_VALUE(r)) {
88 pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
89 "clks", fck_src_name);
90 clk_put(fck_src);
91 return -EINVAL;
92 }
93
94 clk_enable(mcbsp->fclk);
95
96 clk_put(fck_src);
97
98 return 0;
99}
100EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
101
102
55/* Platform data */ 103/* Platform data */
56 104
57#ifdef CONFIG_ARCH_OMAP2420 105#ifdef CONFIG_ARCH_OMAP2420
@@ -190,18 +238,21 @@ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
190 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX, 238 .dma_rx_sync = OMAP44XX_DMA_MCBSP2_RX,
191 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX, 239 .dma_tx_sync = OMAP44XX_DMA_MCBSP2_TX,
192 .tx_irq = OMAP44XX_IRQ_MCBSP2, 240 .tx_irq = OMAP44XX_IRQ_MCBSP2,
241 /* XXX .ops ? */
193 }, 242 },
194 { 243 {
195 .phys_base = OMAP44XX_MCBSP3_BASE, 244 .phys_base = OMAP44XX_MCBSP3_BASE,
196 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX, 245 .dma_rx_sync = OMAP44XX_DMA_MCBSP3_RX,
197 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX, 246 .dma_tx_sync = OMAP44XX_DMA_MCBSP3_TX,
198 .tx_irq = OMAP44XX_IRQ_MCBSP3, 247 .tx_irq = OMAP44XX_IRQ_MCBSP3,
248 /* XXX .ops ? */
199 }, 249 },
200 { 250 {
201 .phys_base = OMAP44XX_MCBSP4_BASE, 251 .phys_base = OMAP44XX_MCBSP4_BASE,
202 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX, 252 .dma_rx_sync = OMAP44XX_DMA_MCBSP4_RX,
203 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX, 253 .dma_tx_sync = OMAP44XX_DMA_MCBSP4_TX,
204 .tx_irq = OMAP44XX_IRQ_MCBSP4, 254 .tx_irq = OMAP44XX_IRQ_MCBSP4,
255 /* XXX .ops ? */
205 }, 256 },
206}; 257};
207#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata) 258#define OMAP44XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap44xx_mcbsp_pdata)
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 886d0e610aa7..4da6f94ae8e8 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -320,6 +320,10 @@
320#define FSR_SRC_FSR 0 320#define FSR_SRC_FSR 0
321#define FSR_SRC_FSX 1 321#define FSR_SRC_FSX 1
322 322
323/* McBSP functional clock sources */
324#define MCBSP_CLKS_PAD_SRC 0
325#define MCBSP_CLKS_PRCM_SRC 1
326
323/* we don't do multichannel for now */ 327/* we don't do multichannel for now */
324struct omap_mcbsp_reg_cfg { 328struct omap_mcbsp_reg_cfg {
325 u16 spcr2; 329 u16 spcr2;
@@ -406,6 +410,7 @@ struct omap_mcbsp_spi_cfg {
406struct omap_mcbsp_ops { 410struct omap_mcbsp_ops {
407 void (*request)(unsigned int); 411 void (*request)(unsigned int);
408 void (*free)(unsigned int); 412 void (*free)(unsigned int);
413 int (*set_clks_src)(u8, u8);
409}; 414};
410 415
411struct omap_mcbsp_platform_data { 416struct omap_mcbsp_platform_data {
@@ -472,6 +477,9 @@ struct omap_mcbsp {
472extern struct omap_mcbsp **mcbsp_ptr; 477extern struct omap_mcbsp **mcbsp_ptr;
473extern int omap_mcbsp_count, omap_mcbsp_cache_size; 478extern int omap_mcbsp_count, omap_mcbsp_cache_size;
474 479
480#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
481#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
482
475int omap_mcbsp_init(void); 483int omap_mcbsp_init(void);
476void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, 484void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
477 int size); 485 int size);
@@ -509,6 +517,9 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int leng
509int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word); 517int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word);
510int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word); 518int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 * word);
511 519
520
521/* McBSP functional clock source changing function */
522extern int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id);
512/* SPI specific API */ 523/* SPI specific API */
513void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg); 524void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg);
514 525
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 9836fb5dc013..09f8c2871334 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -81,9 +81,6 @@ static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
81#define MCBSP_READ_CACHE(mcbsp, reg) \ 81#define MCBSP_READ_CACHE(mcbsp, reg) \
82 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1) 82 omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1)
83 83
84#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
85#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
86
87#define MCBSP_ST_READ(mcbsp, reg) \ 84#define MCBSP_ST_READ(mcbsp, reg) \
88 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg) 85 omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg)
89#define MCBSP_ST_WRITE(mcbsp, reg, val) \ 86#define MCBSP_ST_WRITE(mcbsp, reg, val) \